From af295ead510a2ece5ab9110f7efba801673e640b Mon Sep 17 00:00:00 2001 From: Fischer Moseley <42497969+fischermoseley@users.noreply.github.com> Date: Sun, 2 Apr 2023 13:54:34 -0400 Subject: [PATCH] logic analyzer appears to kinda work in simulation. buggy, but working! --- src/manta/__init__.py | 11 +- src/manta/la_fsm.v | 17 ++- src/manta/logic_analyzer.v | 3 + src/manta/sample_mem.v | 25 ++-- src/manta/trigger_block.v | 19 ++- test/hdl_tb/logic_analyzer_tb.sv | 246 +++++++++++++++++-------------- 6 files changed, 181 insertions(+), 140 deletions(-) diff --git a/src/manta/__init__.py b/src/manta/__init__.py index 813bbcc..cf94ef6 100644 --- a/src/manta/__init__.py +++ b/src/manta/__init__.py @@ -41,9 +41,10 @@ class UARTInterface: if "verbose" in config: self.verbose = config["verbose"] - # open port - import serial - self.ser = serial.Serial(self.port, self.baudrate) + def open_port_if_not_alredy_open(self): + if not hasattr(self, "ser"): + import serial + self.ser = serial.Serial(self.port, self.baudrate) def autodetect_port(self): # as far as I know the FT2232 is the only chip used on the icestick/digilent boards, so just look for that @@ -65,6 +66,8 @@ class UARTInterface: return rd[0].device if rd[0].location > rd[1].location else rd[1].device def read_register(self, addr): + self.open_port_if_not_alredy_open() + # request from the bus addr_str = '{:04X}'.format(addr) request = f"M{addr_str}\r\n".encode('ascii') @@ -91,6 +94,8 @@ class UARTInterface: return data def write_register(self, addr, data): + self.open_port_if_not_alredy_open() + # request from the bus addr_str = '{:04X}'.format(addr) data_str = '{:04X}'.format(data) diff --git a/src/manta/la_fsm.v b/src/manta/la_fsm.v index 12549b7..d2fc558 100644 --- a/src/manta/la_fsm.v +++ b/src/manta/la_fsm.v @@ -8,6 +8,7 @@ module la_fsm( input wire [$clog2(SAMPLE_DEPTH):0] fifo_size, output reg fifo_acquire, output reg fifo_pop, + output reg fifo_clear, // input port input wire [15:0] addr_i, @@ -28,10 +29,11 @@ module la_fsm( // state machine localparam IDLE = 0; - localparam MOVE_TO_POSITION = 1; - localparam IN_POSITION = 2; - localparam FILLING_BUFFER = 3; - localparam FILLED = 4; + localparam START_CAPTURE = 1; + localparam MOVE_TO_POSITION = 2; + localparam IN_POSITION = 3; + localparam FILLING_BUFFER = 4; + localparam FILLED = 5; reg [3:0] state; reg signed [15:0] trigger_loc; @@ -76,7 +78,14 @@ module la_fsm( present_loc <= (trigger_loc < 0) ? trigger_loc : 0; end + else if(state == START_CAPTURE) begin + // perform whatever setup is needed before starting the next capture + fifo_clear <= 1; + state <= MOVE_TO_POSITION; + end + else if(state == MOVE_TO_POSITION) begin + fifo_clear <= 0; // if trigger location is negative or zero, // then we're already in position if(trigger_loc <= 0) state <= IN_POSITION; diff --git a/src/manta/logic_analyzer.v b/src/manta/logic_analyzer.v index 2e80aeb..9918b25 100644 --- a/src/manta/logic_analyzer.v +++ b/src/manta/logic_analyzer.v @@ -36,6 +36,7 @@ module logic_analyzer( .fifo_size(fifo_size), .fifo_acquire(fifo_acquire), .fifo_pop(fifo_pop), + .fifo_clear(fifo_clear), .addr_i(addr_i), .wdata_i(wdata_i), @@ -59,6 +60,7 @@ module logic_analyzer( reg [$clog2(SAMPLE_DEPTH):0] fifo_size; reg fifo_acquire; reg fifo_pop; + reg fifo_clear; // trigger block @@ -98,6 +100,7 @@ module logic_analyzer( .acquire(fifo_acquire), .pop(fifo_pop), .size(fifo_size), + .clear(fifo_clear), // probes .larry(larry), diff --git a/src/manta/sample_mem.v b/src/manta/sample_mem.v index 51a1ec9..3ac317b 100644 --- a/src/manta/sample_mem.v +++ b/src/manta/sample_mem.v @@ -7,7 +7,8 @@ module sample_mem( // fifo input wire acquire, input wire pop, - output wire [AW:0] size, + output wire [BRAM_ADDR_WIDTH:0] size, + input wire clear, // probes input wire larry, @@ -31,9 +32,10 @@ module sample_mem( parameter BASE_ADDR = 0; parameter SAMPLE_DEPTH = 0; - + localparam BRAM_ADDR_WIDTH = $clog2(SAMPLE_DEPTH); + // bus controller - reg [$clog2(SAMPLE_DEPTH):0] bram_read_addr; + reg [BRAM_ADDR_WIDTH-1:0] bram_read_addr; reg [15:0] bram_read_data; always @(*) begin @@ -91,7 +93,7 @@ module sample_mem( .rsta(1'b0), .ena(1'b1), .addra(bram_read_addr), - .dina(), + .dina(16'b0), .wea(1'b0), .regcea(1'b1), .douta(bram_read_data), @@ -100,24 +102,23 @@ module sample_mem( .clkb(clk), .rstb(1'b0), .enb(1'b1), - .addrb(write_pointer), - .dinb({larry, curly, moe, shemp}), + .addrb(write_pointer[BRAM_ADDR_WIDTH-1:0]), + .dinb({9'b0, larry, curly, moe, shemp}), .web(acquire), .regceb(1'b1), .doutb()); // fifo - localparam AW = $clog2(SAMPLE_DEPTH); - - reg [AW:0] write_pointer = 0; - reg [AW:0] read_pointer = 0; + reg [BRAM_ADDR_WIDTH:0] write_pointer = 0; + reg [BRAM_ADDR_WIDTH:0] read_pointer = 0; assign size = write_pointer - read_pointer; always @(posedge clk) begin - if (acquire) write_pointer <= write_pointer + 1'd1; - if (pop) read_pointer <= read_pointer + 1'd1; + if (clear) read_pointer <= write_pointer; + if (acquire && size < SAMPLE_DEPTH) write_pointer <= write_pointer + 1'd1; + if (pop && size > 0) read_pointer <= read_pointer + 1'd1; end endmodule diff --git a/src/manta/trigger_block.v b/src/manta/trigger_block.v index 3efaefe..0614583 100644 --- a/src/manta/trigger_block.v +++ b/src/manta/trigger_block.v @@ -33,8 +33,8 @@ module trigger_block( // - each probe gets an operation and a compare register // - at the end we OR them all together. along with any custom probes the user specs - reg [3:0] larry_trigger_op; - reg larry_trigger_arg; + reg [3:0] larry_trigger_op = 0; + reg larry_trigger_arg = 0; reg larry_trig; trigger #(.INPUT_WIDTH(1)) larry_trigger( .clk(clk), @@ -44,8 +44,8 @@ module trigger_block( .arg(larry_trigger_arg), .trig(larry_trig)); - reg [3:0] curly_trigger_op; - reg curly_trigger_arg; + reg [3:0] curly_trigger_op = 0; + reg curly_trigger_arg = 0; reg curly_trig; trigger #(.INPUT_WIDTH(1)) curly_trigger( .clk(clk), @@ -56,8 +56,8 @@ module trigger_block( .trig(curly_trig)); - reg [3:0] moe_trigger_op; - reg moe_trigger_arg; + reg [3:0] moe_trigger_op = 0; + reg moe_trigger_arg = 0; reg moe_trig; trigger #(.INPUT_WIDTH(1)) moe_trigger( .clk(clk), @@ -67,8 +67,8 @@ module trigger_block( .arg(moe_trigger_arg), .trig(moe_trig)); - reg [3:0] shemp_trigger_op; - reg [3:0] shemp_trigger_arg; + reg [3:0] shemp_trigger_op = 0; + reg [3:0] shemp_trigger_arg = 0; reg shemp_trig; trigger #(.INPUT_WIDTH(4)) shemp_trigger( .clk(clk), @@ -78,8 +78,7 @@ module trigger_block( .arg(shemp_trigger_arg), .trig(shemp_trig)); - reg triggered; - assign triggered = larry_trig || curly_trig || moe_trig || shemp_trig; + assign trig = larry_trig || curly_trig || moe_trig || shemp_trig; // perform register operations always @(posedge clk) begin diff --git a/test/hdl_tb/logic_analyzer_tb.sv b/test/hdl_tb/logic_analyzer_tb.sv index 70ed79d..3bf56a7 100644 --- a/test/hdl_tb/logic_analyzer_tb.sv +++ b/test/hdl_tb/logic_analyzer_tb.sv @@ -3,6 +3,48 @@ `define CP 10 `define HCP 5 +task read_reg ( + input [15:0] addr, + output [15:0] data + ); + + logic_analyzer_tb.tb_la_addr = addr; + logic_analyzer_tb.tb_la_rw = 0; + logic_analyzer_tb.tb_la_valid = 1; + #`CP + logic_analyzer_tb.tb_la_valid = 0; + while (!logic_analyzer_tb.la_tb_valid) #`CP; + data = logic_analyzer_tb.la_tb_rdata; + + endtask + +task write_reg( + input [15:0] addr, + input [15:0] data + ); + + logic_analyzer_tb.tb_la_addr = addr; + logic_analyzer_tb.tb_la_wdata = data; + logic_analyzer_tb.tb_la_rw = 1; + logic_analyzer_tb.tb_la_valid = 1; + #`CP + logic_analyzer_tb.tb_la_valid = 0; + while (!logic_analyzer_tb.la_tb_valid) #`CP; + +endtask + +task read_all_reg(); + for(int i = 0; i < (logic_analyzer_tb.la.sample_mem.BASE_ADDR + logic_analyzer_tb.la.SAMPLE_DEPTH); i++) begin + + if(i == logic_analyzer_tb.la.fsm.BASE_ADDR) $display(" -> FSM MEMORY"); + if(i == logic_analyzer_tb.la.trig_blk.BASE_ADDR) $display(" -> TRIG BLK MEMORY"); + if(i == logic_analyzer_tb.la.sample_mem.BASE_ADDR) $display(" -> SAMPLE MEM MEMORY"); + + read_reg(i, logic_analyzer_tb.read_value); + $display(" -> addr: 0x%h rdata: 0x%b", i, logic_analyzer_tb.read_value); + end +endtask + module logic_analyzer_tb; // boilerplate @@ -58,6 +100,8 @@ module logic_analyzer_tb; clk = !clk; end + reg [15:0] read_value; + initial begin $dumpfile("logic_analyzer_tb.vcd"); $dumpvars(0, logic_analyzer_tb); @@ -83,60 +127,29 @@ module logic_analyzer_tb; $display("\n=== test 1: read state register ==="); test_num = 1; - tb_la_addr = 0; - tb_la_valid = 1; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; - $display(" -> read 0x%h from state reg (addr 0x0000)", la_tb_rdata); - + read_reg(0, read_value); + $display(" -> read 0x%h from state reg (addr 0x0000)", read_value); #(10*`CP); /* ==== Test 1 End ==== */ - /* ==== Test 2 Begin ==== */ $display("\n=== test 2: write to state register and verify ==="); test_num = 2; - // write - tb_la_addr = 0; - tb_la_valid = 1; - tb_la_rw = 1; - tb_la_wdata = 5; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; + write_reg(0, 5); $display(" -> wrote 0x0005 to state reg (addr 0x0000)"); - // read - tb_la_valid = 1; - tb_la_rw = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; - $display(" -> read 0x%h from state reg (addr 0x0000)", la_tb_rdata); + read_reg(0, read_value); + $display(" -> read 0x%h from state reg (addr 0x0000)", read_value); - // write - tb_la_addr = 0; - tb_la_valid = 1; - tb_la_rw = 1; - tb_la_wdata = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; + write_reg(0, 0); $display(" -> wrote 0x0000 to state reg (addr 0x0000)"); - // read - tb_la_valid = 1; - tb_la_rw = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; + read_reg(0, read_value); $display(" -> read 0x%h from state reg (addr 0x0000)", la_tb_rdata); - #(10*`CP); /* ==== Test 2 End ==== */ @@ -146,42 +159,17 @@ module logic_analyzer_tb; $display("\n=== test 3: write to trigger_loc register and verify ==="); test_num = 3; - // write - tb_la_addr = 1; - tb_la_valid = 1; - tb_la_rw = 1; - tb_la_wdata = -16'sd69; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; + write_reg(1, -16'sd69); $display(" -> wrote -0d69 to trigger_loc reg (addr 0x0001)"); - // read - tb_la_valid = 1; - tb_la_rw = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; - $display(" -> read 0d%d from trigger_loc reg (addr 0x0001)", $signed(la_tb_rdata)); + read_reg(1, read_value); + $display(" -> read 0d%d from trigger_loc reg (addr 0x0001)", $signed(read_value)); - // write - tb_la_addr = 1; - tb_la_valid = 1; - tb_la_rw = 1; - tb_la_wdata = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; + write_reg(1, 0); $display(" -> wrote 0x0000 to trigger_loc reg (addr 0x0001)"); - // read - tb_la_valid = 1; - tb_la_rw = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; - $display(" -> read 0x%h from trigger_loc reg (addr 0x0001)", $signed(la_tb_rdata)); - + read_reg(1, read_value); + $display(" -> read 0x%h from trigger_loc reg (addr 0x0001)", $signed(read_value)); #(10*`CP); /* ==== Test 3 End ==== */ @@ -192,24 +180,11 @@ module logic_analyzer_tb; $display("\n=== test 4: configure larry_op for equality and verify ==="); test_num = 4; - // write - tb_la_addr = 2; - tb_la_valid = 1; - tb_la_rw = 1; - tb_la_wdata = 8; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; + write_reg(2, 8); $display(" -> wrote 0x0008 to larry_op reg (addr 0x0002)"); - // read - tb_la_valid = 1; - tb_la_rw = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; - $display(" -> read 0x%h from larry_op reg (addr 0x0002)", la_tb_rdata); - + read_reg(2, read_value); + $display(" -> read 0x%h from larry_op reg (addr 0x0002)", read_value); #(10*`CP); /* ==== Test 4 End ==== */ @@ -220,24 +195,11 @@ module logic_analyzer_tb; $display("\n=== test 5: write 0x0001 to larry_arg register and verify ==="); test_num = 5; - // write - tb_la_addr = 3; - tb_la_valid = 1; - tb_la_rw = 1; - tb_la_wdata = 1; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; + write_reg(3, 1); $display(" -> wrote 0x0001 to larry_arg reg (addr 0x0003)"); - // read - tb_la_valid = 1; - tb_la_rw = 0; - #`CP - tb_la_valid = 0; - while (!la_tb_valid) #`CP; - $display(" -> read 0x%h from larry_arg reg (addr 0x0003)", la_tb_rdata); - + read_reg(3, read_value); + $display(" -> read 0x%h from larry_arg reg (addr 0x0003)", read_value); #(10*`CP); /* ==== Test 5 End ==== */ @@ -251,7 +213,6 @@ module logic_analyzer_tb; $display(" -> set larry = 1"); larry = 1; - // read $display(" -> la core is in state 0x%h", la.fsm.state); $display(" -> wait a clock cycle"); #`CP @@ -259,7 +220,6 @@ module logic_analyzer_tb; $display(" -> set larry = 0"); larry = 0; - #(10*`CP); /* ==== Test 6 End ==== */ @@ -269,14 +229,7 @@ module logic_analyzer_tb; $display("\n=== test 7: set larry = 1, verify core does trigger ==="); test_num = 7; - // write - tb_la_addr = 0; - tb_la_valid = 1; - tb_la_rw = 1; - tb_la_wdata = 1; - #`CP - tb_la_valid = 0; - #`CP + write_reg(0, 1); $display(" -> wrote 0x0001 to state reg (addr 0x0000)"); #`CP @@ -290,10 +243,81 @@ module logic_analyzer_tb; #`CP $display(" -> la core is in state 0x%h", la.fsm.state); + // run until the FILLED state is reached + $display(" -> wait until FILLED state is reached"); + while (la.fsm.state != la.fsm.FILLED) begin + {larry, curly, moe, shemp} = {larry, curly, moe, shemp} + 1; + #`CP; + end + + $display(" -> read from sample memory:"); + read_all_reg(); #(200*`CP); /* ==== Test 7 End ==== */ + + /* ==== Test 8 Begin ==== */ + $display("\n=== test 8: change trigger to fire on shemp > 3, and verify ==="); + test_num = 8; + + write_reg(8, 6); + $display(" -> wrote 0x0006 to shemp_op reg (addr 0x0008)"); + + read_reg(8, read_value); + $display(" -> read 0x%h from shemp_op reg (addr 0x0008)", la_tb_rdata); + + write_reg(9, 3); + $display(" -> wrote 0x0003 to shemp_arg reg (addr 0x0009)"); + + read_reg(9, read_value); + $display(" -> read 0x%h from shemp_arg reg (addr 0x0009)", read_value); + + #(10*`CP); + /* ==== Test 8 End ==== */ + + /* ==== Test 9 Begin ==== */ + $display("\n=== test 9: set state machine to IDLE, verify core does not trigger ==="); + test_num = 9; + + read_reg(0, read_value); + $display(" -> read 0x%h from state reg (addr 0x0000)", read_value); + + write_reg(0, 0); + $display(" -> wrote 0x0000 to state reg (addr 0x0000)"); + + read_reg(0, read_value); + $display(" -> read 0x%h from state reg (addr 0x0000)", read_value); + /* ==== Test 9 End ==== */ + + /* ==== Test 10 Begin ==== */ + $display("\n=== test 10: set shemp = 4, verify core does trigger ==="); + test_num = 10; + + larry = 0; + curly = 0; + moe = 0; + shemp = 0; + + write_reg(0, 1); + $display(" -> wrote 0x0001 to state reg (addr 0x0000)"); + + shemp = 4; + $display(" -> set shemp = 4"); + + // run until the FILLED state is reached + $display(" -> wait until FILLED state is reached"); + while (la.fsm.state != la.fsm.FILLED) begin + {larry, curly, moe, shemp} = {larry, curly, moe, shemp} + 2; + #`CP; + end + + $display(" -> read from sample memory:"); + read_all_reg(); + + #(200*`CP); + /* ==== Test 10 End ==== */ + $finish(); end endmodule