Skip to content

Commit

Permalink
Merge pull request #46 from stefanlippuner/same-label-c
Browse files Browse the repository at this point in the history
Omit duplicate defines in C Headers
  • Loading branch information
tgingold-cern authored Jun 11, 2024
2 parents a3dc38c + 2e7b759 commit 1db5c3b
Show file tree
Hide file tree
Showing 15 changed files with 220 additions and 9 deletions.
3 changes: 2 additions & 1 deletion proto/cheby/gen_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ def gen_c_cheby(fd, root, style):

csym = to_cmacro(root.name)
fd.write("#ifndef {}\n".format(csym))
fd.write("#define {}\n".format(csym))
fd.write("#define {}\n\n".format(csym))
fd.write("#include <stdint.h>\n\n")

# Add the includes for submaps
submaps = [n.name for n in cp.submaps]
Expand Down
10 changes: 9 additions & 1 deletion proto/cheby/print_consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,15 @@ def pr_address(self, n):
def pr_field(self, f):
if f.hi is None:
# A single bit
self.pr_hex_const(self.pr_name(f), self.compute_mask(f))
if self.sep != "_" or f.parent.c_name != f.c_name:
# If there is a register containing a single field and both share the same
# name, both of their c_name s will be equal. Hence, when the default
# separator "_" is selected, pr_name() will return the same name for the
# register as well as for the field. Printing the address for the register
# and the field will therefore lead to the same constant printed twice.
# In that case, this condition blocks the field address constant to be
# printed here.
self.pr_hex_const(self.pr_name(f), self.compute_mask(f))
else:
# A multi-bit field
self.pr_hex_const(self.pr_name(f) + '_MASK', self.compute_mask(f))
Expand Down
38 changes: 31 additions & 7 deletions proto/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ def elab_sv(sv_file, top_entity):
if res.returncode != 0:
error('SV/Verilog elaboration failed for {}'.format(sv_file))

def check_c_syntax(c_file):
"""Function to check C syntax using gcc"""
res = subprocess.run(['gcc', '-fsyntax-only', '-Wall', '-Werror', c_file])
if res.returncode != 0:
error('C syntax check failed for {}'.format(c_file))

def parse_ok(f):
try:
return parser.parse_yaml(f)
Expand Down Expand Up @@ -162,18 +168,26 @@ def test_layout():
print('test layout: {}'.format(f))
t = parse_ok(srcdir + f)
layout_ok(t)

# Generate C source and header files, check syntax for both version
hname = t.name + '.h'
cname = t.name + '.c'
gen_name.gen_name_memmap(t)
with open(cname, 'w') as fd:
gen_laychk.gen_chklayout_cheby(fd, t)
with open(hname, 'w') as fd:
gen_c.gen_c_cheby(fd, t, 'neutral')
if args.elaborate:
check_c_syntax(hname)
check_c_syntax(cname)

with open(hname, 'w') as fd:
gen_c.gen_c_cheby(fd, t, 'arm')
with open(cname, 'w') as fd:
gen_laychk.gen_chklayout_cheby(fd, t)
subprocess.check_call(['gcc', '-S', cname])
if args.elaborate:
check_c_syntax(hname)
check_c_syntax(cname)
hfiles.append(hname)
os.remove(cname)
os.remove(t.name + '.s')
nbr_tests += 1
for f in hfiles:
os.remove(f)
Expand Down Expand Up @@ -258,7 +272,8 @@ def test_genc_ref():
global nbr_tests
for f in ['issue103/top',
'bug-gen-c-02/mbox_regs', 'bug-gen-c-02/fip_urv_regs',
'issue67/repeatInRepeat', 'issue67/repeatInRepeatC']:
'issue67/repeatInRepeat', 'issue67/repeatInRepeatC',
'bug-same-label/same_label']:
h_file = srcdir + f + '.h'
cheby_file = srcdir + f + '.cheby'
t = parse_ok(cheby_file)
Expand All @@ -268,6 +283,12 @@ def test_genc_ref():
gen_c.gen_c_cheby(buf, t, 'neutral')
if not compare_buffer_and_file(buf, h_file):
error('c header generation error for {}'.format(f))

# Check C syntax
# Note: Exclude issue103/top because it includes other header files
# not generated here.
if f != 'issue103/top' and args.elaborate:
check_c_syntax(h_file)
nbr_tests += 1


Expand Down Expand Up @@ -872,7 +893,7 @@ def test_consts():
for f in ['demo_all', 'features/semver1', 'features/mapinfo1',
'issue64/simple_reg1', 'issue_g2/reg', 'bug-consts/blkpfx',
'features/enums1', 'features/enums2', 'bug-const-range/const_range',
'features/memwide_ua']:
'features/memwide_ua', 'bug-same-label/same_label']:
if args.verbose:
print('test consts: {}'.format(f))
chebfile = srcdir + f + '.cheby'
Expand Down Expand Up @@ -903,6 +924,9 @@ def test_consts():

# We don't test SV elaboration here because Verilator requires a top-level instance

if style == 'h':
check_c_syntax(file)

nbr_tests += 1

def test_doc():
Expand Down Expand Up @@ -982,7 +1006,7 @@ def main():
aparser.add_argument('-v', '--verbose', action='store_true', help='Enable additional prints.')
aparser.add_argument('-r', '--regen', action='store_true', help='Regenerate golden test files.')
aparser.add_argument('-k', '--keep', action='store_true', help='Keep running tests after an error occured.')
aparser.add_argument('-e', '--elaborate', action='store_true', help='Enable elaboration tests.')
aparser.add_argument('-e', '--elaborate', action='store_true', help='Enable elaboration/compilation tests.')
args = aparser.parse_args()

try:
Expand Down
3 changes: 3 additions & 0 deletions testfiles/bug-gen-c-02/fip_urv_regs.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef __CHEBY__FIP_URV_REGS__H__
#define __CHEBY__FIP_URV_REGS__H__

#include <stdint.h>


#include "mbox_regs.h"
#define FIP_URV_REGS_SIZE 16384 /* 0x4000 = 16KB */

Expand Down
3 changes: 3 additions & 0 deletions testfiles/bug-gen-c-02/mbox_regs.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#ifndef __CHEBY__MBOX_REGS__H__
#define __CHEBY__MBOX_REGS__H__

#include <stdint.h>

#define MBOX_REGS_SIZE 12 /* 0xc */

/* Mailbox to the fip urv */
Expand Down
13 changes: 13 additions & 0 deletions testfiles/bug-same-label/same_label-consts.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#define SAME_LABEL_REG_SIZE 16
#define ADDR_SAME_LABEL_REG_NO_FIELDS 0x0UL
#define SAME_LABEL_REG_NO_FIELDS_PRESET 0x20UL
#define ADDR_SAME_LABEL_REG_SAME_NAME 0x4UL
#define SAME_LABEL_REG_SAME_NAME_OFFSET 0
#define SAME_LABEL_REG_SAME_NAME 0x1UL
#define ADDR_SAME_LABEL_REG_SAME_NAME_MULTI 0x8UL
#define SAME_LABEL_REG_SAME_NAME_MULTI_OFFSET 0
#define SAME_LABEL_REG_SAME_NAME_MULTI 0xfffUL
#define ADDR_SAME_LABEL_REG_NOT_SAME_REG 0xcUL
#define ADDR_SAME_LABEL_REG_NOT_SAME 0xcUL
#define SAME_LABEL_REG_NOT_SAME_OFFSET 0
#define SAME_LABEL_REG_NOT_SAME 0x1UL
15 changes: 15 additions & 0 deletions testfiles/bug-same-label/same_label-consts.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package same_label_reg_Consts;
localparam SAME_LABEL_REG_SIZE = 16;
localparam ADDR_SAME_LABEL_REG_NO_FIELDS = 'h0;
localparam SAME_LABEL_REG_NO_FIELDS_PRESET = 8'h20;
localparam ADDR_SAME_LABEL_REG_SAME_NAME = 'h4;
localparam SAME_LABEL_REG_SAME_NAME_OFFSET = 0;
localparam SAME_LABEL_REG_SAME_NAME = 32'h1;
localparam ADDR_SAME_LABEL_REG_SAME_NAME_MULTI = 'h8;
localparam SAME_LABEL_REG_SAME_NAME_MULTI_OFFSET = 0;
localparam SAME_LABEL_REG_SAME_NAME_MULTI = 32'hfff;
localparam ADDR_SAME_LABEL_REG_NOT_SAME_REG = 'hc;
localparam ADDR_SAME_LABEL_REG_NOT_SAME = 'hc;
localparam SAME_LABEL_REG_NOT_SAME_OFFSET = 0;
localparam SAME_LABEL_REG_NOT_SAME = 32'h1;
endpackage
13 changes: 13 additions & 0 deletions testfiles/bug-same-label/same_label-consts.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
`define SAME_LABEL_REG_SIZE 16
`define ADDR_SAME_LABEL_REG_NO_FIELDS 'h0
`define SAME_LABEL_REG_NO_FIELDS_PRESET 'h20
`define ADDR_SAME_LABEL_REG_SAME_NAME 'h4
`define SAME_LABEL_REG_SAME_NAME_OFFSET 0
`define SAME_LABEL_REG_SAME_NAME 'h1
`define ADDR_SAME_LABEL_REG_SAME_NAME_MULTI 'h8
`define SAME_LABEL_REG_SAME_NAME_MULTI_OFFSET 0
`define SAME_LABEL_REG_SAME_NAME_MULTI 'hfff
`define ADDR_SAME_LABEL_REG_NOT_SAME_REG 'hc
`define ADDR_SAME_LABEL_REG_NOT_SAME 'hc
`define SAME_LABEL_REG_NOT_SAME_OFFSET 0
`define SAME_LABEL_REG_NOT_SAME 'h1
15 changes: 15 additions & 0 deletions testfiles/bug-same-label/same_label-consts.vhdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
library ieee;
use ieee.std_logic_1164.all;

package same_label_reg_Consts is
constant SAME_LABEL_REG_SIZE : Natural := 16;
constant ADDR_SAME_LABEL_REG_NO_FIELDS : Natural := 16#0#;
constant SAME_LABEL_REG_NO_FIELDS_PRESET : std_logic_vector(8-1 downto 0) := x"20";
constant ADDR_SAME_LABEL_REG_SAME_NAME : Natural := 16#4#;
constant SAME_LABEL_REG_SAME_NAME_OFFSET : Natural := 0;
constant ADDR_SAME_LABEL_REG_SAME_NAME_MULTI : Natural := 16#8#;
constant SAME_LABEL_REG_SAME_NAME_MULTI_OFFSET : Natural := 0;
constant ADDR_SAME_LABEL_REG_NOT_SAME_REG : Natural := 16#c#;
constant ADDR_SAME_LABEL_REG_NOT_SAME : Natural := 16#c#;
constant SAME_LABEL_REG_NOT_SAME_OFFSET : Natural := 0;
end package same_label_reg_Consts;
15 changes: 15 additions & 0 deletions testfiles/bug-same-label/same_label-consts.vhdl-ohwr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
library ieee;
use ieee.std_logic_1164.all;

package same_label_reg_consts_pkg is
constant c_SAME_LABEL_REG_SIZE : Natural := 16;
constant c_SAME_LABEL_REG_NO_FIELDS_ADDR : Natural := 16#0#;
constant c_SAME_LABEL_REG_NO_FIELDS_PRESET : std_logic_vector(8-1 downto 0) := x"20";
constant c_SAME_LABEL_REG_SAME_NAME_ADDR : Natural := 16#4#;
constant c_SAME_LABEL_REG_SAME_NAME_OFFSET : Natural := 0;
constant c_SAME_LABEL_REG_SAME_NAME_MULTI_ADDR : Natural := 16#8#;
constant c_SAME_LABEL_REG_SAME_NAME_MULTI_OFFSET : Natural := 0;
constant c_SAME_LABEL_REG_NOT_SAME_REG_ADDR : Natural := 16#c#;
constant c_ADDR_SAME_LABEL_REG_NOT_SAME : Natural := 16#c#;
constant c_SAME_LABEL_REG_NOT_SAME_OFFSET : Natural := 0;
end package same_label_reg_consts_pkg;
49 changes: 49 additions & 0 deletions testfiles/bug-same-label/same_label.cheby
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
memory-map:
bus: apb-32
name: same_label_reg
x-hdl:
iogroup: regs
pipeline: rd-out
bus-error: True
wmask: True
reg-prefix: false # generate shorter register names
description: 'Register map with same label.'
children:
- reg:
name: no_fields
description: 'Register without fields.'
type: unsigned
width: 8
x-hdl:
type: const
access: ro
preset: 32
- reg:
name: same_name
description: 'Register with same-name field.'
width: 32
access: ro
x-hdl:
read-strobe: True
children:
- field:
name: same_name
range: 0
- reg:
name: same_name_multi
description: 'Register with multi-bit same-name field.'
width: 32
access: ro
children:
- field:
name: same_name_multi
range: 11-0
- reg:
name: not_same_reg
description: 'Register with different-name field.'
width: 32
access: ro
children:
- field:
name: not_same
range: 0
43 changes: 43 additions & 0 deletions testfiles/bug-same-label/same_label.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef __CHEBY__SAME_LABEL_REG__H__
#define __CHEBY__SAME_LABEL_REG__H__

#include <stdint.h>

#define SAME_LABEL_REG_SIZE 16 /* 0x10 */

/* Register without fields. */
#define SAME_LABEL_REG_NO_FIELDS 0x0UL
#define SAME_LABEL_REG_NO_FIELDS_PRESET 0x20UL

/* Register with same-name field. */
#define SAME_LABEL_REG_SAME_NAME 0x4UL

/* Register with multi-bit same-name field. */
#define SAME_LABEL_REG_SAME_NAME_MULTI 0x8UL
#define SAME_LABEL_REG_SAME_NAME_MULTI_MASK 0xfffUL
#define SAME_LABEL_REG_SAME_NAME_MULTI_SHIFT 0

/* Register with different-name field. */
#define SAME_LABEL_REG_NOT_SAME_REG 0xcUL
#define SAME_LABEL_REG_NOT_SAME 0x1UL

#ifndef __ASSEMBLER__
struct same_label_reg {
/* [0x0]: REG (ro) Register without fields. */
uint8_t no_fields;

/* padding to: 4 Bytes */
uint8_t __padding_0[3];

/* [0x4]: REG (ro) Register with same-name field. */
uint32_t same_name;

/* [0x8]: REG (ro) Register with multi-bit same-name field. */
uint32_t same_name_multi;

/* [0xc]: REG (ro) Register with different-name field. */
uint32_t not_same_reg;
};
#endif /* !__ASSEMBLER__*/

#endif /* __CHEBY__SAME_LABEL_REG__H__ */
3 changes: 3 additions & 0 deletions testfiles/issue103/top.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#ifndef __CHEBY__TOP__H__
#define __CHEBY__TOP__H__

#include <stdint.h>


#include "sub1.h"
#include "sub2.h"
#include "sub3.h"
Expand Down
3 changes: 3 additions & 0 deletions testfiles/issue67/repeatInRepeat.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#ifndef __CHEBY__REPEATINREPEAT__H__
#define __CHEBY__REPEATINREPEAT__H__

#include <stdint.h>

#define REPEATINREPEAT_SIZE 32 /* 0x20 */

/* None */
Expand Down
3 changes: 3 additions & 0 deletions testfiles/issue67/repeatInRepeatC.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#ifndef __CHEBY__REPEATINREPEATC__H__
#define __CHEBY__REPEATINREPEATC__H__

#include <stdint.h>

#define REPEATINREPEATC_SIZE 32 /* 0x20 */

/* None */
Expand Down

0 comments on commit 1db5c3b

Please sign in to comment.