working tb, very slow but ok for 20 designs
diff --git a/configure.py b/configure.py index e0b2308..41c0f61 100755 --- a/configure.py +++ b/configure.py
@@ -44,6 +44,12 @@ except IndexError: return "scan_wrapper_{}_{}".format(self.wokwi_ids[self.default_project], id) + def get_wokwi_id(self, id): + try: + return self.wokwi_ids[id] + except IndexError: + return self.wokwi_ids[self.default_project] + def get_macro_gds_name(self, id): try: return "scan_wrapper_{}.gds".format(self.wokwi_ids[id]) @@ -301,6 +307,7 @@ fh.write(assigns.format(NUM_PROJECTS)) fh.write(scan_controller_template) for i in range(NUM_PROJECTS): + logging.debug("instance {} {}".format(i, self.projects.get_macro_name(i))) # instantiate template instance = lesson_template.format(instance=self.projects.get_macro_instance(i), name=self.projects.get_macro_name(i), id=i, next_id=i + 1) fh.write(instance)
diff --git a/verilog/dv/scan_controller/scan_wrapper.py b/verilog/dv/scan_controller/scan_wrapper.py deleted file mode 100644 index 8e9ecce..0000000 --- a/verilog/dv/scan_controller/scan_wrapper.py +++ /dev/null
@@ -1,68 +0,0 @@ -import cocotb -from cocotb.clock import Clock -from cocotb.triggers import RisingEdge, FallingEdge, ClockCycles, Timer -clock_period_ns = 10 - -def convert_to_int(data): - num = 0 - for i in range(8): - if data[7-i]: - num += (1 << i) - return num - -async def scan_clock(dut, cycles=1): - for i in range(cycles): - dut.clk_in.value = 1 - await Timer(clock_period_ns, units='ns') - dut.clk_in.value = 0 - await Timer(clock_period_ns, units='ns') - -async def preload(dut): - # prepare for loading the scan chain - dut.scan_select_in.value = 0 - dut.latch_enable_in.value = 0 - #dut.data_in.value = 0 - await scan_clock(dut, 1) - -async def latch(dut): - # latch the data from the chain into the module - dut.latch_enable_in.value = 1 - await Timer(clock_period_ns, units='ns') - dut.latch_enable_in.value = 0 - -async def capture_data(dut): - # capture the module's output into the scan chain - data = [] - dut.scan_select_in.value = 1 - await scan_clock(dut, 1) - - # dump the data out of the chain - dut.scan_select_in.value = 0 - for i in range(8): - await scan_clock(dut, 1) - data.append(dut.data_out.value) - return data - -async def reset(dut): - data = [0, 0, 0, 0, 0, 0, 1, 0] - await load_data(dut, data) - data = [0, 0, 0, 0, 0, 0, 1, 1] - await load_data(dut, data) - data = [0, 0, 0, 0, 0, 0, 0, 0] - await load_data(dut, data) - -async def single_cycle(dut): - data = [0, 0, 0, 0, 0, 0, 0, 1] - await load_data(dut, data) - data = [0, 0, 0, 0, 0, 0, 0, 0] - await load_data(dut, data) - -async def load_data(dut, data): - await preload(dut) - for i in range(8): - dut.data_in.value = data[i] - await scan_clock(dut, 1) - # TODO why have to wait an extra cycle here? - await scan_clock(dut, 1) - await latch(dut) -
diff --git a/verilog/dv/scan_controller/test_scan_controller.gtkw b/verilog/dv/scan_controller/test_scan_controller.gtkw index 425db70..13e729c 100644 --- a/verilog/dv/scan_controller/test_scan_controller.gtkw +++ b/verilog/dv/scan_controller/test_scan_controller.gtkw
@@ -1,9 +1,9 @@ [*] [*] GTKWave Analyzer v3.3.103 (w)1999-2019 BSI -[*] Fri Aug 26 14:01:08 2022 +[*] Fri Aug 26 16:35:14 2022 [*] [dumpfile] "/home/matt/work/asic-workshop/shuttle7/tinytapeout-mpw7/verilog/dv/scan_controller/test_scan_controller.vcd" -[dumpfile_mtime] "Fri Aug 26 13:59:55 2022" +[dumpfile_mtime] "Fri Aug 26 16:31:15 2022" [dumpfile_size] 9424599 [savefile] "/home/matt/work/asic-workshop/shuttle7/tinytapeout-mpw7/verilog/dv/scan_controller/test_scan_controller.gtkw" [timestart] 0 @@ -13,8 +13,6 @@ [treeopen] test_scan_controller_tb. [treeopen] test_scan_controller_tb.user_project_wrapper. [treeopen] test_scan_controller_tb.user_project_wrapper.scan_wrapper_339501025136214612_0. -[treeopen] test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12. -[treeopen] test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module. [sst_width] 507 [signals_width] 265 [sst_expanded] 1 @@ -24,9 +22,9 @@ test_scan_controller_tb.reset @24 test_scan_controller_tb.user_project_wrapper.active_select[8:0] -@c00022 +@800023 test_scan_controller_tb.user_project_wrapper.inputs[7:0] -@28 +@29 (0)test_scan_controller_tb.user_project_wrapper.inputs[7:0] (1)test_scan_controller_tb.user_project_wrapper.inputs[7:0] (2)test_scan_controller_tb.user_project_wrapper.inputs[7:0] @@ -35,7 +33,7 @@ (5)test_scan_controller_tb.user_project_wrapper.inputs[7:0] (6)test_scan_controller_tb.user_project_wrapper.inputs[7:0] (7)test_scan_controller_tb.user_project_wrapper.inputs[7:0] -@1401200 +@1001201 -group_end @800022 test_scan_controller_tb.user_project_wrapper.outputs[7:0] @@ -81,29 +79,5 @@ -group_end @1401200 -module 0 -@800200 --module 12 -@28 -test_scan_controller_tb.user_project_wrapper.scan_wrapper_339501025136214612_0.data_out -@c00022 -test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -@28 -(0)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -(1)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -(2)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -(3)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -(4)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -(5)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -(6)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -(7)test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_in[7:0] -@1401200 --group_end -@22 -test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.user_module.io_out[7:0] -@28 -test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.scan_select_in -test_scan_controller_tb.user_project_wrapper.scan_wrapper_340805072482992722_12.latch_enable_in -@1000200 --module 12 [pattern_trace] 1 [pattern_trace] 0
diff --git a/verilog/dv/scan_controller/test_scan_controller.py b/verilog/dv/scan_controller/test_scan_controller.py index 311a276..a53f624 100644 --- a/verilog/dv/scan_controller/test_scan_controller.py +++ b/verilog/dv/scan_controller/test_scan_controller.py
@@ -1,11 +1,12 @@ import cocotb from cocotb.clock import Clock from cocotb.triggers import RisingEdge, FallingEdge, ClockCycles -from scan_wrapper import * +#from scan_wrapper import * # utility functions. using 2nd bit as reset and 1st bit as clock for synchronous design examples async def reset(dut): for i in range(2): + print("reset cycle {}".format(i)) await RisingEdge(dut.ready); dut.inputs.value = 0b10 await RisingEdge(dut.ready);
diff --git a/verilog/rtl/scan_cells.v b/verilog/rtl/scan_cells.v new file mode 100644 index 0000000..227a452 --- /dev/null +++ b/verilog/rtl/scan_cells.v
@@ -0,0 +1,115 @@ +`define default_netname none + +module buffer_cell ( + input wire in, + output wire out + ); + assign out = in; +endmodule + +module and_cell ( + input wire a, + input wire b, + output wire out + ); + + assign out = a & b; +endmodule + +module or_cell ( + input wire a, + input wire b, + output wire out + ); + + assign out = a | b; +endmodule + +module xor_cell ( + input wire a, + input wire b, + output wire out + ); + + assign out = a ^ b; +endmodule + +module nand_cell ( + input wire a, + input wire b, + output wire out + ); + + assign out = !(a&b); +endmodule + +module not_cell ( + input wire in, + output wire out + ); + + assign out = !in; +endmodule + +module mux_cell ( + input wire a, + input wire b, + input wire sel, + output wire out + ); + + assign out = sel ? b : a; +endmodule + +module dff_cell ( + input wire clk, + input wire d, + output reg q, + output wire notq + ); + + assign notq = !q; + always @(posedge clk) + q <= d; + +endmodule + +module dffsr_cell ( + input wire clk, + input wire d, + input wire s, + input wire r, + output reg q, + output wire notq + ); + + assign notq = !q; + + always @(posedge clk or posedge s or posedge r) begin + if (r) + q <= '0; + else if (s) + q <= '1; + else + q <= d; + end +endmodule + +// for scan wrapper +module latch (GATE, D, Q); + input GATE, D; + output Q; + reg Q; + always @ (GATE or D) + if (GATE) + Q <= D; +endmodule + +module scan_flop(CLK, D, SCD, SCE, Q); + input CLK, D, SCD, SCE; + output Q; + reg Q; + + always @(posedge CLK) + Q <= SCE ? SCD : D; +endmodule