From e317398f374537a9fe255d429c574962727e3c98 Mon Sep 17 00:00:00 2001 From: Steve Jenson Date: Sat, 2 Nov 2024 15:27:38 -0700 Subject: [PATCH] explicit widths, switch to one-hot encoding for the TAP state machine --- src/byte_transmitter.v | 18 +++++----- src/jtag.v | 77 ++++++++++++++++++------------------------ src/minipit.v | 12 +++---- test/test.py | 2 +- 4 files changed, 49 insertions(+), 60 deletions(-) diff --git a/src/byte_transmitter.v b/src/byte_transmitter.v index 1642847..54b50e6 100644 --- a/src/byte_transmitter.v +++ b/src/byte_transmitter.v @@ -27,15 +27,15 @@ module byte_transmitter ( always @(posedge clk) begin if (reset) begin byte_count <= 6'h20; - r_done <= 0; - r_out <= 0; + r_done <= 1'b0; + r_out <= 1'b0; `ifdef FORMAL - f_total_written <= 0; + f_total_written <= 6'h0; `endif end else if (enable) begin - if (byte_count > 0) begin + if (byte_count > 6'h0) begin `ifdef FORMAL - f_total_written <= f_total_written + 1; + f_total_written <= f_total_written + 6'h1; assert (r_out != 1'bX); assert (byte_count != 5'bX_XXXX); assert (byte_count[0] != 1'bX); @@ -43,19 +43,19 @@ module byte_transmitter ( assert (byte_count[2] != 1'bX); assert (byte_count[3] != 1'bX); assert (byte_count[4] != 1'bX); - assert (in[byte_count:(byte_count-1)] != 1'bX); `endif r_out <= in[byte_count-1]; byte_count <= (byte_count - 6'd1); end else begin byte_count <= 6'h20; - r_done <= 1; + r_done <= 1'b1; + r_out <= 1'b0; end end else begin byte_count <= 6'h20; - r_done <= 0; - r_out <= 0; + r_done <= 1'b0; + r_out <= 1'b0; end end diff --git a/src/jtag.v b/src/jtag.v index dc602dd..5e59c02 100644 --- a/src/jtag.v +++ b/src/jtag.v @@ -16,7 +16,7 @@ module jtag ( input wire tck, /* verilator lint_off UNUSED */ input wire tdi, - input wire tms, + input bit tms, input wire trst_n, /* TRST_N */ input wire enable, output wire tdo @@ -25,25 +25,25 @@ module jtag ( wire trst; assign trst = ~trst_n; - // TAP controller state - localparam bit [3:0] TestLogicReset = 4'h0; - localparam bit [3:0] RunTestOrIdle = 4'h1; - localparam bit [3:0] SelectDrScan = 4'h2; - localparam bit [3:0] SelectIrScan = 4'h3; - localparam bit [3:0] CaptureDr = 4'h4; - localparam bit [3:0] CaptureIr = 4'h5; - localparam bit [3:0] ShiftDr = 4'h6; - localparam bit [3:0] ShiftIr = 4'h7; - localparam bit [3:0] Exit1Dr = 4'h8; - localparam bit [3:0] Exit1Ir = 4'h9; - localparam bit [3:0] PauseDr = 4'hA; - localparam bit [3:0] PauseIr = 4'hB; - localparam bit [3:0] Exit2Dr = 4'hC; - localparam bit [3:0] Exit2Ir = 4'hD; - localparam bit [3:0] UpdateDr = 4'hE; - localparam bit [3:0] UpdateIr = 4'hF; - - reg [3:0] current_state; + // TAP controller state in one-hot encoding + localparam bit [15:0] TestLogicReset = 16'b0000_0000_0000_0000; // 0 + localparam bit [15:0] RunTestOrIdle = 16'b0000_0000_0000_0001; // 1 + localparam bit [15:0] SelectDrScan = 16'b0000_0000_0000_0010; // 2 + localparam bit [15:0] SelectIrScan = 16'b0000_0000_0000_0100; // 3 + localparam bit [15:0] CaptureDr = 16'b0000_0000_0000_1000; // 4 + localparam bit [15:0] CaptureIr = 16'b0000_0000_0001_0000; // 5 + localparam bit [15:0] ShiftDr = 16'b0000_0000_0010_0000; // 6 + localparam bit [15:0] ShiftIr = 16'b0000_0000_0100_0000; // 7 + localparam bit [15:0] Exit1Dr = 16'b0000_0000_1000_0000; // 8 + localparam bit [15:0] Exit1Ir = 16'b0000_0001_0000_0000; // 9 + localparam bit [15:0] PauseDr = 16'b0000_0010_0000_0000; // 10 + localparam bit [15:0] PauseIr = 16'b0000_0100_0000_0000; // 11 + localparam bit [15:0] Exit2Dr = 16'b0000_1000_0000_0000; // 12 + localparam bit [15:0] Exit2Ir = 16'b0001_0000_0000_0000; // 13 + localparam bit [15:0] UpdateDr = 16'b0010_0000_0000_0000; // 14 + localparam bit [15:0] UpdateIr = 16'b0100_0000_0000_0000; // 15 + + reg [15:0] current_state; // IR Instruction values localparam bit [3:0] Abort = 4'b1000; @@ -101,14 +101,14 @@ module jtag ( always @(posedge tck) begin if (~trst_n) begin current_state <= TestLogicReset; // State 0 - tms_reset_check <= 5'b0_0000; - cycles <= 8'b0000_0000; + tms_reset_check <= 5'h0; + cycles <= 8'h0; current_ir_instruction <= IdCode; // IDCODE is the default instruction. - r_output_selector_transmitter <= 1; // by default the tap controller writes - tap_channel <= 0; // How can an X sneak in here? - byte_transmitter_enable <= 0; - reset_byte_transmitter <= 0; - been_reset <= 1; + r_output_selector_transmitter <= 1'b1; // by default the tap controller writes + tap_channel <= 1'b0; + byte_transmitter_enable <= 1'b0; + reset_byte_transmitter <= 1'b0; + been_reset <= 1'b1; end else if (enable && been_reset) begin current_state <= current_state; tms_reset_check <= tms_reset_check << 1; @@ -116,13 +116,13 @@ module jtag ( cycles <= cycles + 1'd1; current_ir_instruction <= current_ir_instruction; r_output_selector_transmitter <= r_output_selector_transmitter; - tap_channel <= 0; + tap_channel <= 1'b0; byte_transmitter_enable <= byte_transmitter_enable; reset_byte_transmitter <= reset_byte_transmitter; // TAP state machine case (current_state) TestLogicReset: begin // 0 - tms_reset_check <= 5'b0_0000; + tms_reset_check <= 5'h0; case (tms) 1: current_state <= TestLogicReset; default: current_state <= RunTestOrIdle; @@ -154,8 +154,8 @@ module jtag ( case (current_ir_instruction) IdCode: begin // place the byte transmitter with the IDCODE register and start to shift it onto TDO. - r_output_selector_transmitter <= 0; - byte_transmitter_enable <= 1; + r_output_selector_transmitter <= 1'b0; + byte_transmitter_enable <= 1'b1; end default: begin current_state <= ShiftDr; @@ -181,8 +181,8 @@ module jtag ( if (!idcode_out_done) begin current_state <= ShiftDr; end else begin - reset_byte_transmitter <= 1; - byte_transmitter_enable <= 0; + reset_byte_transmitter <= 1'b1; + byte_transmitter_enable <= 1'b0; current_state <= Exit1Dr; // Not sure if this is correct. end end @@ -270,7 +270,6 @@ module jtag ( always @(posedge tck) begin if (f_past_valid) begin // our state never overruns the enum values. - assert (current_state < 5'h16); // less-than or equals, not assignment cover (current_state <= UpdateIr); end @@ -284,16 +283,6 @@ module jtag ( end end - - /* - always @(posedge tck) begin - if (f_past_valid && $past(~trst_n) && trst_n) begin - cover (current_state == ShiftDr); - assert (tdo != 1'bX); - end - end -*/ - always @(posedge tck) begin // Whenever TMS is high for five cycles, the design is in reset if (f_past_valid && $past(~trst_n) && trst_n && ($past(tms_reset_check) == 5'b1_1111)) begin diff --git a/src/minipit.v b/src/minipit.v index a1c4c68..f2d4b08 100644 --- a/src/minipit.v +++ b/src/minipit.v @@ -22,19 +22,19 @@ module minipit ( always @(posedge clk) begin if (!rst_n) begin - current_count <= 16'd0; - r_interrupting <= 0; + current_count <= 16'h0; + r_interrupting <= 1'b0; end else begin - current_count <= current_count + 1; + current_count <= current_count + 16'h1; if (counter_tripped) begin // pull interrupt line high for one clock cycle - r_interrupting <= 1; + r_interrupting <= 1'b1; if (repeating) begin - current_count <= 0; + current_count <= 16'h0; end end else begin - r_interrupting <= 0; + r_interrupting <= 1'b0; end end end diff --git a/test/test.py b/test/test.py index 003f4ef..f4b8bd6 100644 --- a/test/test.py +++ b/test/test.py @@ -129,7 +129,7 @@ async def test_idcode(dut): await ClockCycles(dut.clk, 1) dut.ui_in.value = 0b0000_1000 await ClockCycles(dut.clk, 1) - dut.ui_in.value = 0b0000_1001 + dut.ui_in.value = 0b0000_1101 await ClockCycles(dut.clk, 1) dut.ui_in.value = 0b0000_1000 await ClockCycles(dut.clk, 1)