From a5427d704a9620b7ebbf552523141dcc4604d199 Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Sun, 21 Apr 2024 14:17:05 -0400 Subject: [PATCH 1/2] icebox_vlog: use proper Verilog-2001 module declarations Resolves #328 Summary: - By default emit Verilog-2001 style module declarations with direction and signal type defined in the module prototype and not in the body of the module - Add -C option to output Verilog-1995 module declarations for compatibility with older toolchains - Add some comments to the file to assist future maintainers Background: Currently, icebox_vlog outputs a mixed-style module declaration in which it puts the port direction in the module prototype and later declares the signals as ports or wires. ```verilog module chip (input pin1, output pin2); wire pin1; reg pin2 = 0; ``` The inclusion of the direction in the module prototype is a feature of newer Verilog-2001 specification. It seems probable that older versions of Icarus Verilog had some leeway in handling this mixed-style of declaration. But, it seems that at least the version included in newer Ubuntu distributions considers this to be a syntax error. In this commit, the module declaration above will be emitted as: ```verilog module chip (input wire pin1, output reg pin2 = 0); ``` Or if you sepcificy the -C option for Verilog-1995 compatibility: ```verilog module chip (pin1, pin2); input pin1; output pin2; wire pin1; reg pin2 = 0; ``` --- icebox/icebox_vlog.py | 129 ++++++++++++++++++++++++++++++++---------- 1 file changed, 99 insertions(+), 30 deletions(-) diff --git a/icebox/icebox_vlog.py b/icebox/icebox_vlog.py index 74ac3d3dac..0fb272d10d 100755 --- a/icebox/icebox_vlog.py +++ b/icebox/icebox_vlog.py @@ -26,6 +26,7 @@ check_driver = False lookup_symbols = False do_collect = False +v95_compatibility = False package = None pcf_data = dict() portnames = set() @@ -70,11 +71,14 @@ def usage(): -D enable exactly-one-driver checks + + -C + use old Verilog-1995 module declarations (for compatibility) """ % os.path.basename(sys.argv[0])) sys.exit(0) try: - opts, args = getopt.getopt(sys.argv[1:], "sSlLap:P:n:d:cRD") + opts, args = getopt.getopt(sys.argv[1:], "sSlLap:P:n:d:cRDC") except: usage() @@ -125,6 +129,8 @@ def usage(): check_ieren = True elif o == "-D": check_driver = True + elif o == "-C": + v95_compatibility = True else: usage() @@ -140,8 +146,11 @@ def usage(): ic.read_file(args[0]) print() -text_wires = list() -text_ports = list() +# these variables store text representations that will end up printed to the +# output to create the body of the verilog file +text_wires = list() # all wires in the body of the module +text_ports = list() # all ports in the module declaration +v95_module_text_ports = list() # port signal declarations without decoration luts_queue = set() special_5k_queue = set() @@ -870,58 +879,118 @@ def make_lut_expr(bits, sigs): text_func.append("assign %-*s = %s;" % (max_net_len, a[0], a[1])) if do_collect: - new_text_ports = set() + new_text_ports = list() vec_ports_min = dict() vec_ports_max = dict() vec_ports_dir = dict() for port in text_ports: + # find ports with [x] subscripts to combine into [a:b] style busses match = re_match_cached(r"(input|output|inout) (.*)\[(\d+)\] ?$", port); if match: vec_ports_min[match.group(2)] = min(vec_ports_min.setdefault(match.group(2), int(match.group(3))), int(match.group(3))) vec_ports_max[match.group(2)] = max(vec_ports_max.setdefault(match.group(2), int(match.group(3))), int(match.group(3))) vec_ports_dir[match.group(2)] = match.group(1) else: - new_text_ports.add(port) + new_text_ports.append(port) + if v95_compatibility: + # strip direction from text used in module declaration + port=str(port.split()[-1:][0]) + v95_module_text_ports.append("%s%s" % (port, ' ' if port.startswith("\\") else '')) for port, direct in list(vec_ports_dir.items()): min_idx = vec_ports_min[port] max_idx = vec_ports_max[port] - new_text_ports.add("%s [%d:%d] %s " % (direct, max_idx, min_idx, port)) - text_ports = list(new_text_ports) - -print("module %s (%s);\n" % (modname, ", ".join(text_ports))) - -new_text_wires = list() -new_text_regs = list() -new_text_raw = list() -for line in text_wires: + new_text_ports.append("%s wire [%d:%d] %s " % (direct, max_idx, min_idx, port)) + if v95_compatibility: + # strip direction and dimensions from text used in module declaration + v95_module_text_ports.append("%s%s" % (port, ' ' if port.startswith("\\") else '')) + text_ports = new_text_ports + +if not do_collect: + if v95_compatibility: + # strip direction from from text used in module declaration + for port in text_ports: + port=str(port.split()[-1:][0]) + v95_module_text_ports.append("%s%s" % (port, ' ' if port.startswith("\\") else '')) + +# these variables used to normalize/filter the output +new_text_wires = list() # list of wire names to declare at top of module +new_text_regs = list() # list of reg names to declare at top of module +new_text_raw = list() # remaining content not moved to previous 2 variables +vec_ports_type = dict() # track which ports should be reg vs wire +temp_flat_ports = " ".join(text_ports) # temp variable + +for line in text_wires: #note - continue in loop body (twice) + # match wire declarations (not comments, assigns, etc) match = re_match_cached(r"wire ([^ ;]+)(.*)", line) if match: + name = match.group(1) + lineend = match.group(2) + isreg = (name in wire_to_reg) + isport = (name in temp_flat_ports) + if not v95_compatibility and isport: + # find the port declration and store off its type + for port in text_ports: #note - break in loop body + if name in port: + vec_ports_type[port] = "reg" if isreg else "wire" + break # break inner loop when any match found + continue # continue outer loop if strip_comments: - name = match.group(1) + # strip_comments will also compact reg and wire declarations + # 10 per line with comma separation + # names starting with \ can't immediately have a comma after them + # so insert a space in the name + proper_name = name if name.startswith("\\"): - name += " " - if match.group(1) in wire_to_reg: - new_text_regs.append(name) + proper_name += " " + if isreg: + new_text_regs.append(proper_name) else: - new_text_wires.append(name) - continue + new_text_wires.append(proper_name) + continue # continue outer loop else: - if match.group(1) in wire_to_reg: - line = "reg " + match.group(1) + " = 0" + match.group(2) - if strip_comments: - new_text_raw.append(line) - else: - print(line) -for names in [new_text_wires[x:x+10] for x in range(0, len(new_text_wires), 10)]: - print("wire %s;" % ", ".join(names)) -for names in [new_text_regs[x:x+10] for x in range(0, len(new_text_regs), 10)]: - print("reg %s = 0;" % " = 0, ".join(names)) + if isreg: + line = "reg " + name + " = 0" + lineend + new_text_raw.append(line) + +# BEGIN PRINTING THE VERILOG OUTPUT +# print the module declaration +if not v95_compatibility: + print("module %s (" % modname, end=''); + separator = "" + for port in text_ports: + iotype = vec_ports_type.get(port) + if iotype: + # insert the reg/wire designator after the port direction + port = port.replace(" ", " %s " % iotype, 1) + print("%s%s%s" % (separator, port, " = 0" if "reg"==iotype else ""), end='') + separator=", " + print(");\n") +else: + # use v95_module_text_ports with stripped metadata + print("module %s (%s);" % (modname, ", ".join(v95_module_text_ports))) + # print verbose port declaration on lines after the module declaration + for line in text_ports: + print(line, end=";\n") + print() + +# print module body if strip_comments: + for names in [new_text_wires[x:x+10] for x in range(0, len(new_text_wires), 10)]: + print("wire %s;" % ", ".join(names)) + for names in [new_text_regs[x:x+10] for x in range(0, len(new_text_regs), 10)]: + print("reg %s = 0;" % " = 0, ".join(names)) for line in new_text_raw: print(line) print() +else: + for line in new_text_raw: + print(line) if do_collect: + # when collecing ports into busses, the module declaration is changed to + # create a bus interface as a wire + # individual component signals may be wire or reg, so assign the signals + # to the bus port here for port, direct in list(vec_ports_dir.items()): min_idx = vec_ports_min[port] max_idx = vec_ports_max[port] From 95990fb2fc611ca019f4547b21f70ee743030017 Mon Sep 17 00:00:00 2001 From: Chris Baker Date: Sun, 21 Apr 2024 15:15:08 -0400 Subject: [PATCH 2/2] icebox_vlog: add basic test cases Makefile provides various targets for testing icebox_vlog. - %_syn.v targets will use icebox_vlog to generate a .v file from the blinky.asc file - %_syntb targets will invoke iverilog on the .v files - %.json targets will invoke yosys on the .v files - test target will attempt several combinations of command line options for icebox_vlog (all combinations of -s, -l, -p, -c, -C) and will then trigger iverilog and yosys targets to attempt parsing the .v files Output files generated by `make test` can be compared after making code changes to icebox_vlog.py to identify any regressions. --- icebox/testcase/.gitignore | 8 ++++ icebox/testcase/Makefile | 73 ++++++++++++++++++++++++++++++ icebox/testcase/blinky-C_stb.v | 1 + icebox/testcase/blinky-Cc_stb.v | 1 + icebox/testcase/blinky-Ccp_stb.v | 1 + icebox/testcase/blinky-Cl_stb.v | 1 + icebox/testcase/blinky-Clc_stb.v | 1 + icebox/testcase/blinky-Clcp_stb.v | 1 + icebox/testcase/blinky-Clp_stb.v | 1 + icebox/testcase/blinky-Cp_stb.v | 1 + icebox/testcase/blinky-Cs_stb.v | 1 + icebox/testcase/blinky-Csc_stb.v | 1 + icebox/testcase/blinky-Cscp_stb.v | 1 + icebox/testcase/blinky-Csl_stb.v | 1 + icebox/testcase/blinky-Cslc_stb.v | 1 + icebox/testcase/blinky-Cslcp_stb.v | 1 + icebox/testcase/blinky-Cslp_stb.v | 1 + icebox/testcase/blinky-Csp_stb.v | 1 + icebox/testcase/blinky-c_stb.v | 35 ++++++++++++++ icebox/testcase/blinky-cp_stb.v | 1 + icebox/testcase/blinky-l_stb.v | 35 ++++++++++++++ icebox/testcase/blinky-lc_stb.v | 1 + icebox/testcase/blinky-lcp_stb.v | 1 + icebox/testcase/blinky-lp_stb.v | 1 + icebox/testcase/blinky-p_stb.v | 35 ++++++++++++++ icebox/testcase/blinky-s_stb.v | 1 + icebox/testcase/blinky-sc_stb.v | 1 + icebox/testcase/blinky-scp_stb.v | 1 + icebox/testcase/blinky-sl_stb.v | 1 + icebox/testcase/blinky-slc_stb.v | 1 + icebox/testcase/blinky-slcp_stb.v | 1 + icebox/testcase/blinky-slp_stb.v | 1 + icebox/testcase/blinky-sp_stb.v | 1 + icebox/testcase/blinky.pcf | 9 ++++ icebox/testcase/blinky.v | 23 ++++++++++ icebox/testcase/blinky_stb.v | 1 + icebox/testcase/blinky_tb.v | 31 +++++++++++++ 37 files changed, 278 insertions(+) create mode 100644 icebox/testcase/.gitignore create mode 100644 icebox/testcase/Makefile create mode 120000 icebox/testcase/blinky-C_stb.v create mode 120000 icebox/testcase/blinky-Cc_stb.v create mode 120000 icebox/testcase/blinky-Ccp_stb.v create mode 120000 icebox/testcase/blinky-Cl_stb.v create mode 120000 icebox/testcase/blinky-Clc_stb.v create mode 120000 icebox/testcase/blinky-Clcp_stb.v create mode 120000 icebox/testcase/blinky-Clp_stb.v create mode 120000 icebox/testcase/blinky-Cp_stb.v create mode 120000 icebox/testcase/blinky-Cs_stb.v create mode 120000 icebox/testcase/blinky-Csc_stb.v create mode 120000 icebox/testcase/blinky-Cscp_stb.v create mode 120000 icebox/testcase/blinky-Csl_stb.v create mode 120000 icebox/testcase/blinky-Cslc_stb.v create mode 120000 icebox/testcase/blinky-Cslcp_stb.v create mode 120000 icebox/testcase/blinky-Cslp_stb.v create mode 120000 icebox/testcase/blinky-Csp_stb.v create mode 100644 icebox/testcase/blinky-c_stb.v create mode 120000 icebox/testcase/blinky-cp_stb.v create mode 100644 icebox/testcase/blinky-l_stb.v create mode 120000 icebox/testcase/blinky-lc_stb.v create mode 120000 icebox/testcase/blinky-lcp_stb.v create mode 120000 icebox/testcase/blinky-lp_stb.v create mode 100644 icebox/testcase/blinky-p_stb.v create mode 120000 icebox/testcase/blinky-s_stb.v create mode 120000 icebox/testcase/blinky-sc_stb.v create mode 120000 icebox/testcase/blinky-scp_stb.v create mode 120000 icebox/testcase/blinky-sl_stb.v create mode 120000 icebox/testcase/blinky-slc_stb.v create mode 120000 icebox/testcase/blinky-slcp_stb.v create mode 120000 icebox/testcase/blinky-slp_stb.v create mode 120000 icebox/testcase/blinky-sp_stb.v create mode 100644 icebox/testcase/blinky.pcf create mode 100644 icebox/testcase/blinky.v create mode 120000 icebox/testcase/blinky_stb.v create mode 100644 icebox/testcase/blinky_tb.v diff --git a/icebox/testcase/.gitignore b/icebox/testcase/.gitignore new file mode 100644 index 0000000000..3e8c983312 --- /dev/null +++ b/icebox/testcase/.gitignore @@ -0,0 +1,8 @@ +*.asc +*.json +*_tb +*_syntb +*_syn.v +*.vcd +*.rpt +*.bin diff --git a/icebox/testcase/Makefile b/icebox/testcase/Makefile new file mode 100644 index 0000000000..4c96405729 --- /dev/null +++ b/icebox/testcase/Makefile @@ -0,0 +1,73 @@ +PROJ = blinky + +PIN_DEF = blinky.pcf +DEVICE = hx1k +PACKAGE = tq144 +icebox_vlog_test_params := s l p c sl sp sc lp lc cp slp slc scp lcp slcp + +all: test + +test: icebox_vlog_test + +# Create test target list for icebox_vlog with different parameter options +# composed of the case with no options, all of the options specified in +# $(icebox_vlog_test_params), and all of the same cases with -C (Verilog-1995) +# compatibilty. +icebox_vlog_output := $(PROJ)_syn.v $(PROJ)-C_syn.v \ + $(foreach case,$(icebox_vlog_test_params),$(PROJ)-$(case)_syn.v) \ + $(foreach case,$(icebox_vlog_test_params),$(PROJ)-C$(case)_syn.v) +icebox_vlog_iverilog_testlist := $(PROJ)_syntb $(PROJ)-C_syntb \ + $(foreach case,$(icebox_vlog_test_params),$(PROJ)-$(case)_syntb) \ + $(foreach case,$(icebox_vlog_test_params),$(PROJ)-C$(case)_syntb) +icebox_vlog_yosys_testlist := $(PROJ)_syn.json $(PROJ)-C_syn.json \ + $(foreach case,$(icebox_vlog_test_params),$(PROJ)-$(case)_syn.json) \ + $(foreach case,$(icebox_vlog_test_params),$(PROJ)-C$(case)_syn.json) +icebox_vlog_test: $(icebox_vlog_output) $(icebox_vlog_iverilog_testlist) $(icebox_vlog_yosys_testlist) + +%.json: %.v + yosys -p 'synth_ice40 -top $(PROJ) -json $@' $< + +%.asc: $(PIN_DEF) %.json + nextpnr-ice40 --$(DEVICE) --package $(PACKAGE) --asc $@ --pcf $< --json $*.json + +%.bin: %.asc + icepack $< $@ + +%.rpt: %.asc + icetime -d $(DEVICE) -mtr $@ $< + +%_tb: %_tb.v %.v + iverilog -o $@ $^ + +%_tb.vcd: %_tb + vvp -N $< +vcd=$@ + +get_test_params = $(subst p,p $(PIN_DEF),\ + $(filter-out $(1),\ + $(1:$(PROJ)-%_syn.v=-%))) +%_syn.v: $(PROJ).asc + ../icebox_vlog.py -n blinky $(call get_test_params,$@) $^ > $@ + +%_syntb: %_stb.v %_syn.v + iverilog -o $@ $^ + +%_syntb.vcd: %_syntb + vvp -N $< +vcd=$@ + +sim: $(PROJ)_tb.vcd + +postsim: $(PROJ)_syntb.vcd + +prog: $(PROJ).bin + iceprog $< + +sudo-prog: $(PROJ).bin + @echo 'Executing prog as root!!!' + sudo iceprog $< + +clean: + rm -f *.json $(PROJ).asc $(PROJ).rpt $(PROJ).bin \ + *.vcd *_tb *_syntb *_syn.v + +.SECONDARY: +.PHONY: all prog clean test icebox_vlog_test diff --git a/icebox/testcase/blinky-C_stb.v b/icebox/testcase/blinky-C_stb.v new file mode 120000 index 0000000000..6d0e1f0d81 --- /dev/null +++ b/icebox/testcase/blinky-C_stb.v @@ -0,0 +1 @@ +blinky_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cc_stb.v b/icebox/testcase/blinky-Cc_stb.v new file mode 120000 index 0000000000..6d0e1f0d81 --- /dev/null +++ b/icebox/testcase/blinky-Cc_stb.v @@ -0,0 +1 @@ +blinky_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Ccp_stb.v b/icebox/testcase/blinky-Ccp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-Ccp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cl_stb.v b/icebox/testcase/blinky-Cl_stb.v new file mode 120000 index 0000000000..5aba7026d7 --- /dev/null +++ b/icebox/testcase/blinky-Cl_stb.v @@ -0,0 +1 @@ +blinky-l_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Clc_stb.v b/icebox/testcase/blinky-Clc_stb.v new file mode 120000 index 0000000000..5aba7026d7 --- /dev/null +++ b/icebox/testcase/blinky-Clc_stb.v @@ -0,0 +1 @@ +blinky-l_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Clcp_stb.v b/icebox/testcase/blinky-Clcp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-Clcp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Clp_stb.v b/icebox/testcase/blinky-Clp_stb.v new file mode 120000 index 0000000000..bddaa97603 --- /dev/null +++ b/icebox/testcase/blinky-Clp_stb.v @@ -0,0 +1 @@ +blinky-p_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cp_stb.v b/icebox/testcase/blinky-Cp_stb.v new file mode 120000 index 0000000000..bddaa97603 --- /dev/null +++ b/icebox/testcase/blinky-Cp_stb.v @@ -0,0 +1 @@ +blinky-p_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cs_stb.v b/icebox/testcase/blinky-Cs_stb.v new file mode 120000 index 0000000000..6d0e1f0d81 --- /dev/null +++ b/icebox/testcase/blinky-Cs_stb.v @@ -0,0 +1 @@ +blinky_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Csc_stb.v b/icebox/testcase/blinky-Csc_stb.v new file mode 120000 index 0000000000..6d0e1f0d81 --- /dev/null +++ b/icebox/testcase/blinky-Csc_stb.v @@ -0,0 +1 @@ +blinky_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cscp_stb.v b/icebox/testcase/blinky-Cscp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-Cscp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Csl_stb.v b/icebox/testcase/blinky-Csl_stb.v new file mode 120000 index 0000000000..5aba7026d7 --- /dev/null +++ b/icebox/testcase/blinky-Csl_stb.v @@ -0,0 +1 @@ +blinky-l_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cslc_stb.v b/icebox/testcase/blinky-Cslc_stb.v new file mode 120000 index 0000000000..5aba7026d7 --- /dev/null +++ b/icebox/testcase/blinky-Cslc_stb.v @@ -0,0 +1 @@ +blinky-l_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cslcp_stb.v b/icebox/testcase/blinky-Cslcp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-Cslcp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Cslp_stb.v b/icebox/testcase/blinky-Cslp_stb.v new file mode 120000 index 0000000000..bddaa97603 --- /dev/null +++ b/icebox/testcase/blinky-Cslp_stb.v @@ -0,0 +1 @@ +blinky-p_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-Csp_stb.v b/icebox/testcase/blinky-Csp_stb.v new file mode 120000 index 0000000000..bddaa97603 --- /dev/null +++ b/icebox/testcase/blinky-Csp_stb.v @@ -0,0 +1 @@ +blinky-p_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-c_stb.v b/icebox/testcase/blinky-c_stb.v new file mode 100644 index 0000000000..c40375cdb1 --- /dev/null +++ b/icebox/testcase/blinky-c_stb.v @@ -0,0 +1,35 @@ +// From nextpnr:ice40/examples/blinky +// Original file due to Claire Xenia Wolf + +module blinky_tb; + reg clk; + always #5 clk = (clk === 1'b0); + + wire led1, led2, led3, led4, led5; + + blinky uut ( + .io_0_8_1(clk), + .io_13_12_1(led1), + .io_13_12_0(led2), + .io_13_11_1(led3), + .io_13_11_0(led4), + .io_13_9_1(led5) + ); + + reg [4095:0] vcdfile; + + initial begin + if ($value$plusargs("vcd=%s", vcdfile)) begin + $dumpfile(vcdfile); + $dumpvars(0, blinky_tb); + end + end + + initial begin + repeat (10) begin + repeat (900000) @(posedge clk); + $display(led1, led2, led3, led4, led5); + end + $finish; + end +endmodule diff --git a/icebox/testcase/blinky-cp_stb.v b/icebox/testcase/blinky-cp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-cp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-l_stb.v b/icebox/testcase/blinky-l_stb.v new file mode 100644 index 0000000000..b2c4f01546 --- /dev/null +++ b/icebox/testcase/blinky-l_stb.v @@ -0,0 +1,35 @@ +// From nextpnr:ice40/examples/blinky +// Original file due to Claire Xenia Wolf + +module blinky_tb; + reg clk; + always #5 clk = (clk === 1'b0); + + wire led1, led2, led3, led4, led5; + + blinky uut ( + .pin_21(clk), + .pin_95(led1), + .pin_96(led2), + .pin_97(led3), + .pin_98(led4), + .pin_99(led5) + ); + + reg [4095:0] vcdfile; + + initial begin + if ($value$plusargs("vcd=%s", vcdfile)) begin + $dumpfile(vcdfile); + $dumpvars(0, blinky_tb); + end + end + + initial begin + repeat (10) begin + repeat (900000) @(posedge clk); + $display(led1, led2, led3, led4, led5); + end + $finish; + end +endmodule diff --git a/icebox/testcase/blinky-lc_stb.v b/icebox/testcase/blinky-lc_stb.v new file mode 120000 index 0000000000..5aba7026d7 --- /dev/null +++ b/icebox/testcase/blinky-lc_stb.v @@ -0,0 +1 @@ +blinky-l_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-lcp_stb.v b/icebox/testcase/blinky-lcp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-lcp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-lp_stb.v b/icebox/testcase/blinky-lp_stb.v new file mode 120000 index 0000000000..bddaa97603 --- /dev/null +++ b/icebox/testcase/blinky-lp_stb.v @@ -0,0 +1 @@ +blinky-p_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-p_stb.v b/icebox/testcase/blinky-p_stb.v new file mode 100644 index 0000000000..564b1717c1 --- /dev/null +++ b/icebox/testcase/blinky-p_stb.v @@ -0,0 +1,35 @@ +// From nextpnr:ice40/examples/blinky +// Original file due to Claire Xenia Wolf + +module blinky_tb; + reg clk; + always #5 clk = (clk === 1'b0); + + wire led1, led2, led3, led4, led5; + + blinky uut ( + .clki (clk), + .\led[0] (led1), + .\led[1] (led2), + .\led[2] (led3), + .\led[3] (led4), + .\led[4] (led5) + ); + + reg [4095:0] vcdfile; + + initial begin + if ($value$plusargs("vcd=%s", vcdfile)) begin + $dumpfile(vcdfile); + $dumpvars(0, blinky_tb); + end + end + + initial begin + repeat (10) begin + repeat (900000) @(posedge clk); + $display(led1, led2, led3, led4, led5); + end + $finish; + end +endmodule diff --git a/icebox/testcase/blinky-s_stb.v b/icebox/testcase/blinky-s_stb.v new file mode 120000 index 0000000000..6d0e1f0d81 --- /dev/null +++ b/icebox/testcase/blinky-s_stb.v @@ -0,0 +1 @@ +blinky_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-sc_stb.v b/icebox/testcase/blinky-sc_stb.v new file mode 120000 index 0000000000..6d0e1f0d81 --- /dev/null +++ b/icebox/testcase/blinky-sc_stb.v @@ -0,0 +1 @@ +blinky_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-scp_stb.v b/icebox/testcase/blinky-scp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-scp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-sl_stb.v b/icebox/testcase/blinky-sl_stb.v new file mode 120000 index 0000000000..5aba7026d7 --- /dev/null +++ b/icebox/testcase/blinky-sl_stb.v @@ -0,0 +1 @@ +blinky-l_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-slc_stb.v b/icebox/testcase/blinky-slc_stb.v new file mode 120000 index 0000000000..5aba7026d7 --- /dev/null +++ b/icebox/testcase/blinky-slc_stb.v @@ -0,0 +1 @@ +blinky-l_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-slcp_stb.v b/icebox/testcase/blinky-slcp_stb.v new file mode 120000 index 0000000000..0f7fb4462f --- /dev/null +++ b/icebox/testcase/blinky-slcp_stb.v @@ -0,0 +1 @@ +blinky_tb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-slp_stb.v b/icebox/testcase/blinky-slp_stb.v new file mode 120000 index 0000000000..bddaa97603 --- /dev/null +++ b/icebox/testcase/blinky-slp_stb.v @@ -0,0 +1 @@ +blinky-p_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky-sp_stb.v b/icebox/testcase/blinky-sp_stb.v new file mode 120000 index 0000000000..bddaa97603 --- /dev/null +++ b/icebox/testcase/blinky-sp_stb.v @@ -0,0 +1 @@ +blinky-p_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky.pcf b/icebox/testcase/blinky.pcf new file mode 100644 index 0000000000..42d205a317 --- /dev/null +++ b/icebox/testcase/blinky.pcf @@ -0,0 +1,9 @@ +# From nextpnr:ice40/examples/blinky +# Original file due to David Shah + +set_io led[0] 99 +set_io led[1] 98 +set_io led[2] 97 +set_io led[3] 96 +set_io led[4] 95 +set_io clki 21 diff --git a/icebox/testcase/blinky.v b/icebox/testcase/blinky.v new file mode 100644 index 0000000000..e31c87318a --- /dev/null +++ b/icebox/testcase/blinky.v @@ -0,0 +1,23 @@ +// From nextpnr:ice40/examples/blinky +// Original file due to Claire Xenia Wolf + +module blinky ( + input clki, + output [4:0] led +); + + assign clk = clki; + + localparam BITS = 5; + localparam LOG2DELAY = 21; + + reg [BITS+LOG2DELAY-1:0] counter = 0; + reg [BITS-1:0] outcnt; + + always @(posedge clk) begin + counter <= counter + 1; + outcnt <= counter >> LOG2DELAY; + end + + assign led = outcnt ^ (outcnt >> 1); +endmodule diff --git a/icebox/testcase/blinky_stb.v b/icebox/testcase/blinky_stb.v new file mode 120000 index 0000000000..4f93d11e5c --- /dev/null +++ b/icebox/testcase/blinky_stb.v @@ -0,0 +1 @@ +blinky-c_stb.v \ No newline at end of file diff --git a/icebox/testcase/blinky_tb.v b/icebox/testcase/blinky_tb.v new file mode 100644 index 0000000000..f0b764e72e --- /dev/null +++ b/icebox/testcase/blinky_tb.v @@ -0,0 +1,31 @@ +// From nextpnr:ice40/examples/blinky +// Original file due to Claire Xenia Wolf + +module blinky_tb; + reg clk; + always #5 clk = (clk === 1'b0); + + wire led1, led2, led3, led4, led5; + + blinky uut ( + .clki (clk), + .\led ({led1, led2, led3, led4, led5}) + ); + + reg [4095:0] vcdfile; + + initial begin + if ($value$plusargs("vcd=%s", vcdfile)) begin + $dumpfile(vcdfile); + $dumpvars(0, blinky_tb); + end + end + + initial begin + repeat (10) begin + repeat (900000) @(posedge clk); + $display(led1, led2, led3, led4, led5); + end + $finish; + end +endmodule