Sun, 06 Mar 2011 21:03:32 +0000
Commit GSI patches from Wesley Terpstra
- Add JTAG capture pin
==> allows removing sensitivity to reg_update which caused clocking problems making JTAG unstable
- Use register file backed by RAM blocks
==> saves quite some area and speed on altera
... be sure to enable it using `define CFG_EBR_POSEDGE_REGISTER_FILE
- Fix a minor problem where compilation fails when interrupts are not supported
- Add support to flush icache and dcache per JTAG
- Fix wrong width assignments for PC
Multiplier patch has been left out for now; don't the design synthesizers (Quartus / Xst) split the multiply automatically?
Original-Author: Wesley Terpstra <w.terpsta gsi.de>
Original-Source: Milkymist mailing list postings, 2011-02-28 (11:19 and 13:32) and 2011-03-01
Original-Message-Ids: <4D6B84B5.9040604@gsi.de> <4D6BA3E4.3020609@gsi.de> <4D6CFFF2.6030703@gsi.de>
jtag_cores.v | file | annotate | diff | revisions | |
jtag_tap_altera.v | file | annotate | diff | revisions | |
jtag_tap_spartan6.v | file | annotate | diff | revisions | |
jtag_tap_xilinx_spartan6.v | file | annotate | diff | revisions | |
lm32_cpu.v | file | annotate | diff | revisions | |
lm32_dp_ram.v | file | annotate | diff | revisions | |
lm32_jtag.v | file | annotate | diff | revisions |
1.1 diff -r 50bf3061dbff -r cc945f778cd7 jtag_cores.v 1.2 --- a/jtag_cores.v Sun Mar 06 19:49:17 2011 +0000 1.3 +++ b/jtag_cores.v Sun Mar 06 21:03:32 2011 +0000 1.4 @@ -1,3 +1,5 @@ 1.5 +// Modified by GSI to use simple positive edge clocking and the JTAG capture state 1.6 + 1.7 module jtag_cores ( 1.8 input [7:0] reg_d, 1.9 input [2:0] reg_addr_d, 1.10 @@ -11,15 +13,19 @@ 1.11 wire tck; 1.12 wire tdi; 1.13 wire tdo; 1.14 +wire capture; 1.15 wire shift; 1.16 wire update; 1.17 +wire e1dr; 1.18 wire reset; 1.19 1.20 jtag_tap jtag_tap ( 1.21 .tck(tck), 1.22 .tdi(tdi), 1.23 .tdo(tdo), 1.24 + .capture(capture), 1.25 .shift(shift), 1.26 + .e1dr(e1dr), 1.27 .update(update), 1.28 .reset(reset) 1.29 ); 1.30 @@ -27,26 +33,28 @@ 1.31 reg [10:0] jtag_shift; 1.32 reg [10:0] jtag_latched; 1.33 1.34 -always @(posedge tck or posedge reset) 1.35 +always @(posedge tck) 1.36 begin 1.37 if(reset) 1.38 jtag_shift <= 11'b0; 1.39 else begin 1.40 - if(shift) 1.41 + if (shift) 1.42 jtag_shift <= {tdi, jtag_shift[10:1]}; 1.43 - else 1.44 + else if (capture) 1.45 jtag_shift <= {reg_d, reg_addr_d}; 1.46 end 1.47 end 1.48 1.49 assign tdo = jtag_shift[0]; 1.50 1.51 -always @(posedge reg_update or posedge reset) 1.52 +always @(posedge tck) 1.53 begin 1.54 if(reset) 1.55 jtag_latched <= 11'b0; 1.56 - else 1.57 - jtag_latched <= jtag_shift; 1.58 + else begin 1.59 + if (e1dr) 1.60 + jtag_latched <= jtag_shift; 1.61 + end 1.62 end 1.63 1.64 assign reg_update = update;
2.1 diff -r 50bf3061dbff -r cc945f778cd7 jtag_tap_altera.v 2.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 +++ b/jtag_tap_altera.v Sun Mar 06 21:03:32 2011 +0000 2.4 @@ -0,0 +1,59 @@ 2.5 +module jtag_tap( 2.6 + output tck, 2.7 + output tdi, 2.8 + input tdo, 2.9 + output capture, 2.10 + output shift, 2.11 + output e1dr, 2.12 + output update, 2.13 + output reset 2.14 +); 2.15 + 2.16 +assign reset = 0; 2.17 +wire nil1, nil2, nil3, nil4; 2.18 + 2.19 +sld_virtual_jtag altera_jtag( 2.20 + .ir_in (), 2.21 + .ir_out (), 2.22 + .tck (tck), 2.23 + .tdo (tdo), 2.24 + .tdi (tdi), 2.25 + .virtual_state_cdr (capture), 2.26 + .virtual_state_sdr (shift), 2.27 + .virtual_state_e1dr (e1dr), 2.28 + .virtual_state_pdr (nil1), 2.29 + .virtual_state_e2dr (nil2), 2.30 + .virtual_state_udr (update), 2.31 + .virtual_state_cir (nil3), 2.32 + .virtual_state_uir (nil4) 2.33 + // synopsys translate_off 2.34 + , 2.35 + .jtag_state_cdr (), 2.36 + .jtag_state_cir (), 2.37 + .jtag_state_e1dr (), 2.38 + .jtag_state_e1ir (), 2.39 + .jtag_state_e2dr (), 2.40 + .jtag_state_e2ir (), 2.41 + .jtag_state_pdr (), 2.42 + .jtag_state_pir (), 2.43 + .jtag_state_rti (), 2.44 + .jtag_state_sdr (), 2.45 + .jtag_state_sdrs (), 2.46 + .jtag_state_sir (), 2.47 + .jtag_state_sirs (), 2.48 + .jtag_state_tlr (), 2.49 + .jtag_state_udr (), 2.50 + .jtag_state_uir (), 2.51 + .tms () 2.52 + // synopsys translate_on 2.53 + ); 2.54 + 2.55 +defparam 2.56 + altera_jtag.sld_auto_instance_index = "YES", 2.57 + altera_jtag.sld_instance_index = 0, 2.58 + altera_jtag.sld_ir_width = 1, 2.59 + altera_jtag.sld_sim_action = "", 2.60 + altera_jtag.sld_sim_n_scan = 0, 2.61 + altera_jtag.sld_sim_total_length = 0; 2.62 + 2.63 +endmodule
3.1 diff -r 50bf3061dbff -r cc945f778cd7 jtag_tap_spartan6.v 3.2 --- a/jtag_tap_spartan6.v Sun Mar 06 19:49:17 2011 +0000 3.3 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.4 @@ -1,33 +0,0 @@ 3.5 - 3.6 -module jtag_tap( 3.7 - output tck, 3.8 - output tdi, 3.9 - input tdo, 3.10 - output shift, 3.11 - output update, 3.12 - output reset 3.13 -); 3.14 - 3.15 -wire g_shift; 3.16 -wire g_update; 3.17 - 3.18 -assign shift = g_shift & sel; 3.19 -assign update = g_update & sel; 3.20 - 3.21 -BSCAN_SPARTAN6 #( 3.22 - .JTAG_CHAIN(1) 3.23 -) bscan ( 3.24 - .CAPTURE(), 3.25 - .DRCK(tck), 3.26 - .RESET(reset), 3.27 - .RUNTEST(), 3.28 - .SEL(sel), 3.29 - .SHIFT(g_shift), 3.30 - .TCK(), 3.31 - .TDI(tdi), 3.32 - .TMS(), 3.33 - .UPDATE(g_update), 3.34 - .TDO(tdo) 3.35 -); 3.36 - 3.37 -endmodule
4.1 diff -r 50bf3061dbff -r cc945f778cd7 jtag_tap_xilinx_spartan6.v 4.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.3 +++ b/jtag_tap_xilinx_spartan6.v Sun Mar 06 21:03:32 2011 +0000 4.4 @@ -0,0 +1,43 @@ 4.5 + 4.6 +module jtag_tap( 4.7 + output tck, 4.8 + output tdi, 4.9 + input tdo, 4.10 + output capture, 4.11 + output shift, 4.12 + output e1dr, 4.13 + output update, 4.14 + output reset 4.15 +); 4.16 + 4.17 +// Unfortunately the exit1 state for DR (e1dr) is mising 4.18 +// We can simulate it by interpretting 'update' as e1dr and delaying 'update' 4.19 +wire g_capture; 4.20 +wire g_shift; 4.21 +wire g_update; 4.22 +reg update_delay; 4.23 + 4.24 +assign capture = g_capture & sel; 4.25 +assign shift = g_shift & sel; 4.26 +assign e1dr = g_update & sel; 4.27 +assign update = update_delay; 4.28 + 4.29 +BSCAN_SPARTAN6 #( 4.30 + .JTAG_CHAIN(1) 4.31 +) bscan ( 4.32 + .CAPTURE(g_capture), 4.33 + .DRCK(tck), 4.34 + .RESET(reset), 4.35 + .RUNTEST(), 4.36 + .SEL(sel), 4.37 + .SHIFT(g_shift), 4.38 + .TCK(), 4.39 + .TDI(tdi), 4.40 + .TMS(), 4.41 + .UPDATE(g_update), 4.42 + .TDO(tdo) 4.43 +); 4.44 + 4.45 +update_delay <= g_update; 4.46 + 4.47 +endmodule
5.1 diff -r 50bf3061dbff -r cc945f778cd7 lm32_cpu.v 5.2 --- a/lm32_cpu.v Sun Mar 06 19:49:17 2011 +0000 5.3 +++ b/lm32_cpu.v Sun Mar 06 21:03:32 2011 +0000 5.4 @@ -1269,70 +1269,44 @@ 5.5 /*---------------------------------------------------------------------- 5.6 Register file instantiation as Pseudo-Dual Port EBRs. 5.7 ----------------------------------------------------------------------*/ 5.8 - pmi_ram_dp 5.9 + // Modified by GSI: removed non-portable RAM instantiation 5.10 + lm32_dp_ram 5.11 #( 5.12 // ----- Parameters ----- 5.13 - .pmi_wr_addr_depth(1<<5), 5.14 - .pmi_wr_addr_width(5), 5.15 - .pmi_wr_data_width(32), 5.16 - .pmi_rd_addr_depth(1<<5), 5.17 - .pmi_rd_addr_width(5), 5.18 - .pmi_rd_data_width(32), 5.19 - .pmi_regmode("noreg"), 5.20 - .pmi_gsr("enable"), 5.21 - .pmi_resetmode("sync"), 5.22 - .pmi_init_file("none"), 5.23 - .pmi_init_file_format("binary"), 5.24 - .pmi_family(`LATTICE_FAMILY), 5.25 - .module_type("pmi_ram_dp") 5.26 + .addr_depth(1<<5), 5.27 + .addr_width(5), 5.28 + .data_width(32) 5.29 ) 5.30 reg_0 5.31 ( 5.32 // ----- Inputs ----- 5.33 - .Data(w_result), 5.34 - .WrAddress(write_idx_w), 5.35 - .RdAddress(instruction_f[25:21]), 5.36 - .WrClock(clk_i), 5.37 - .RdClock(clk_i), 5.38 - .WrClockEn(`TRUE), 5.39 - .RdClockEn(`TRUE), 5.40 - .WE(reg_write_enable_q_w), 5.41 - .Reset(rst_i), 5.42 + .clk_i (clk_i), 5.43 + .rst_i (rst_i), 5.44 + .we_i (reg_write_enable_q_w), 5.45 + .wdata_i (w_result), 5.46 + .waddr_i (write_idx_w), 5.47 + .raddr_i (instruction_f[25:21]), 5.48 // ----- Outputs ----- 5.49 - .Q(regfile_data_0) 5.50 + .rdata_o (regfile_data_0) 5.51 ); 5.52 5.53 - pmi_ram_dp 5.54 + lm32_dp_ram 5.55 #( 5.56 - // ----- Parameters ----- 5.57 - .pmi_wr_addr_depth(1<<5), 5.58 - .pmi_wr_addr_width(5), 5.59 - .pmi_wr_data_width(32), 5.60 - .pmi_rd_addr_depth(1<<5), 5.61 - .pmi_rd_addr_width(5), 5.62 - .pmi_rd_data_width(32), 5.63 - .pmi_regmode("noreg"), 5.64 - .pmi_gsr("enable"), 5.65 - .pmi_resetmode("sync"), 5.66 - .pmi_init_file("none"), 5.67 - .pmi_init_file_format("binary"), 5.68 - .pmi_family(`LATTICE_FAMILY), 5.69 - .module_type("pmi_ram_dp") 5.70 + .addr_depth(1<<5), 5.71 + .addr_width(5), 5.72 + .data_width(32) 5.73 ) 5.74 reg_1 5.75 ( 5.76 // ----- Inputs ----- 5.77 - .Data(w_result), 5.78 - .WrAddress(write_idx_w), 5.79 - .RdAddress(instruction_f[20:16]), 5.80 - .WrClock(clk_i), 5.81 - .RdClock(clk_i), 5.82 - .WrClockEn(`TRUE), 5.83 - .RdClockEn(`TRUE), 5.84 - .WE(reg_write_enable_q_w), 5.85 - .Reset(rst_i), 5.86 + .clk_i (clk_i), 5.87 + .rst_i (rst_i), 5.88 + .we_i (reg_write_enable_q_w), 5.89 + .wdata_i (w_result), 5.90 + .waddr_i (write_idx_w), 5.91 + .raddr_i (instruction_f[20:16]), 5.92 // ----- Outputs ----- 5.93 - .Q(regfile_data_1) 5.94 + .rdata_o (regfile_data_1) 5.95 ); 5.96 `endif 5.97 5.98 @@ -1882,7 +1856,9 @@ 5.99 exception has occured. This stall will ensure that D_CYC_O and 5.100 store_m will both be low for one cycle. 5.101 */ 5.102 +`ifdef CFG_INTERRUPTS_ENABLED 5.103 || ((store_x == `TRUE) && (interrupt_exception == `TRUE)) 5.104 +`endif 5.105 || (load_m == `TRUE) 5.106 || (load_x == `TRUE) 5.107 ) 5.108 @@ -2042,15 +2018,29 @@ 5.109 5.110 // Cache flush 5.111 `ifdef CFG_ICACHE_ENABLED 5.112 -assign iflush = (csr_write_enable_d == `TRUE) 5.113 - && (csr_d == `LM32_CSR_ICC) 5.114 - && (stall_d == `FALSE) 5.115 - && (kill_d == `FALSE) 5.116 - && (valid_d == `TRUE); 5.117 +assign iflush = ( (csr_write_enable_d == `TRUE) 5.118 + && (csr_d == `LM32_CSR_ICC) 5.119 + && (stall_d == `FALSE) 5.120 + && (kill_d == `FALSE) 5.121 + && (valid_d == `TRUE)) 5.122 +// Added by GSI: needed to flush cache after loading firmware per JTAG 5.123 +`ifdef CFG_HW_DEBUG_ENABLED 5.124 + || 5.125 + ( (jtag_csr_write_enable == `TRUE) 5.126 + && (jtag_csr == `LM32_CSR_ICC)) 5.127 +`endif 5.128 + ; 5.129 `endif 5.130 `ifdef CFG_DCACHE_ENABLED 5.131 -assign dflush_x = (csr_write_enable_q_x == `TRUE) 5.132 - && (csr_x == `LM32_CSR_DCC); 5.133 +assign dflush_x = ( (csr_write_enable_q_x == `TRUE) 5.134 + && (csr_x == `LM32_CSR_DCC)) 5.135 +// Added by GSI: needed to flush cache after loading firmware per JTAG 5.136 +`ifdef CFG_HW_DEBUG_ENABLED 5.137 + || 5.138 + ( (jtag_csr_write_enable == `TRUE) 5.139 + && (jtag_csr == `LM32_CSR_DCC)) 5.140 +`endif 5.141 + ; 5.142 `endif 5.143 5.144 // Extract CSR index 5.145 @@ -2252,7 +2242,7 @@ 5.146 operand_0_x <= {`LM32_WORD_WIDTH{1'b0}}; 5.147 operand_1_x <= {`LM32_WORD_WIDTH{1'b0}}; 5.148 store_operand_x <= {`LM32_WORD_WIDTH{1'b0}}; 5.149 - branch_target_x <= {`LM32_WORD_WIDTH{1'b0}}; 5.150 + branch_target_x <= {`LM32_PC_WIDTH{1'b0}}; 5.151 x_result_sel_csr_x <= `FALSE; 5.152 `ifdef LM32_MC_ARITHMETIC_ENABLED 5.153 x_result_sel_mc_arith_x <= `FALSE; 5.154 @@ -2313,7 +2303,7 @@ 5.155 `endif 5.156 csr_write_enable_x <= `FALSE; 5.157 operand_m <= {`LM32_WORD_WIDTH{1'b0}}; 5.158 - branch_target_m <= {`LM32_WORD_WIDTH{1'b0}}; 5.159 + branch_target_m <= {`LM32_PC_WIDTH{1'b0}}; 5.160 m_result_sel_compare_m <= `FALSE; 5.161 `ifdef CFG_PL_BARREL_SHIFT_ENABLED 5.162 m_result_sel_shift_m <= `FALSE;
6.1 diff -r 50bf3061dbff -r cc945f778cd7 lm32_dp_ram.v 6.2 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.3 +++ b/lm32_dp_ram.v Sun Mar 06 21:03:32 2011 +0000 6.4 @@ -0,0 +1,35 @@ 6.5 +module lm32_dp_ram( 6.6 + clk_i, 6.7 + rst_i, 6.8 + we_i, 6.9 + waddr_i, 6.10 + wdata_i, 6.11 + raddr_i, 6.12 + rdata_o); 6.13 + 6.14 +parameter addr_width = 32; 6.15 +parameter addr_depth = 1024; 6.16 +parameter data_width = 8; 6.17 + 6.18 +input clk_i; 6.19 +input rst_i; 6.20 +input we_i; 6.21 +input [addr_width-1:0] waddr_i; 6.22 +input [data_width-1:0] wdata_i; 6.23 +input [addr_width-1:0] raddr_i; 6.24 +output [data_width-1:0] rdata_o; 6.25 + 6.26 +reg [data_width-1:0] ram[addr_depth-1:0]; 6.27 + 6.28 +reg [addr_width-1:0] raddr_r; 6.29 +assign rdata_o = ram[raddr_r]; 6.30 + 6.31 +always @ (posedge clk_i) 6.32 +begin 6.33 + if (we_i) 6.34 + ram[waddr_i] <= wdata_i; 6.35 + raddr_r <= raddr_i; 6.36 +end 6.37 + 6.38 +endmodule 6.39 +
7.1 diff -r 50bf3061dbff -r cc945f778cd7 lm32_jtag.v 7.2 --- a/lm32_jtag.v Sun Mar 06 19:49:17 2011 +0000 7.3 +++ b/lm32_jtag.v Sun Mar 06 21:03:32 2011 +0000 7.4 @@ -170,13 +170,15 @@ 7.5 // Internal nets and registers 7.6 ///////////////////////////////////////////////////// 7.7 7.8 -reg rx_toggle; // Clock-domain crossing registers 7.9 -reg rx_toggle_r; // Registered version of rx_toggle 7.10 -reg rx_toggle_r_r; // Registered version of rx_toggle_r 7.11 -reg rx_toggle_r_r_r; // Registered version of rx_toggle_r_r 7.12 +reg rx_update; // Clock-domain crossing registers 7.13 +reg rx_update_r; // Registered version of rx_update 7.14 +reg rx_update_r_r; // Registered version of rx_update_r 7.15 +reg rx_update_r_r_r; // Registered version of rx_update_r_r 7.16 7.17 -reg [`LM32_BYTE_RNG] rx_byte; 7.18 -reg [2:0] rx_addr; 7.19 +// These wires come from the JTAG clock domain. 7.20 +// They have been held unchanged for an entire JTAG clock cycle before the jtag_update toggle flips 7.21 +wire [`LM32_BYTE_RNG] rx_byte; 7.22 +wire [2:0] rx_addr; 7.23 7.24 `ifdef CFG_JTAG_UART_ENABLED 7.25 reg [`LM32_BYTE_RNG] uart_tx_byte; // UART TX data 7.26 @@ -229,36 +231,26 @@ 7.27 // Sequential Logic 7.28 ///////////////////////////////////////////////////// 7.29 7.30 -// Toggle a flag when a JTAG write occurs 7.31 - 7.32 -always @(negedge jtag_update `CFG_RESET_SENSITIVITY) 7.33 -begin 7.34 -if (rst_i == `TRUE) 7.35 - rx_toggle <= 1'b0; 7.36 -else 7.37 - rx_toggle <= ~rx_toggle; 7.38 -end 7.39 +assign rx_byte = jtag_reg_q; 7.40 +assign rx_addr = jtag_reg_addr_q; 7.41 7.42 -always @(*) 7.43 -begin 7.44 - rx_byte = jtag_reg_q; 7.45 - rx_addr = jtag_reg_addr_q; 7.46 -end 7.47 - 7.48 -// Clock domain crossing from JTAG clock domain to CPU clock domain 7.49 +// The JTAG latched jtag_reg[_addr]_q at least one JTCK before jtag_update is raised 7.50 +// Thus, they are stable (and safe to sample) when jtag_update is high 7.51 always @(posedge clk_i `CFG_RESET_SENSITIVITY) 7.52 begin 7.53 if (rst_i == `TRUE) 7.54 begin 7.55 - rx_toggle_r <= 1'b0; 7.56 - rx_toggle_r_r <= 1'b0; 7.57 - rx_toggle_r_r_r <= 1'b0; 7.58 + rx_update <= 1'b0; 7.59 + rx_update_r <= 1'b0; 7.60 + rx_update_r_r <= 1'b0; 7.61 + rx_update_r_r_r <= 1'b0; 7.62 end 7.63 else 7.64 begin 7.65 - rx_toggle_r <= rx_toggle; 7.66 - rx_toggle_r_r <= rx_toggle_r; 7.67 - rx_toggle_r_r_r <= rx_toggle_r_r; 7.68 + rx_update <= jtag_update; 7.69 + rx_update_r <= rx_update; 7.70 + rx_update_r_r <= rx_update_r; 7.71 + rx_update_r_r_r <= rx_update_r_r; 7.72 end 7.73 end 7.74 7.75 @@ -319,7 +311,7 @@ 7.76 `LM32_JTAG_STATE_READ_COMMAND: 7.77 begin 7.78 // Wait for rx register to toggle which indicates new data is available 7.79 - if (rx_toggle_r_r != rx_toggle_r_r_r) 7.80 + if ((~rx_update_r_r_r & rx_update_r_r) == `TRUE) 7.81 begin 7.82 command <= rx_byte[7:4]; 7.83 case (rx_addr) 7.84 @@ -384,7 +376,7 @@ 7.85 `ifdef CFG_HW_DEBUG_ENABLED 7.86 `LM32_JTAG_STATE_READ_BYTE_0: 7.87 begin 7.88 - if (rx_toggle_r_r != rx_toggle_r_r_r) 7.89 + if ((~rx_update_r_r_r & rx_update_r_r) == `TRUE) 7.90 begin 7.91 jtag_byte_0 <= rx_byte; 7.92 state <= `LM32_JTAG_STATE_READ_BYTE_1; 7.93 @@ -392,7 +384,7 @@ 7.94 end 7.95 `LM32_JTAG_STATE_READ_BYTE_1: 7.96 begin 7.97 - if (rx_toggle_r_r != rx_toggle_r_r_r) 7.98 + if ((~rx_update_r_r_r & rx_update_r_r) == `TRUE) 7.99 begin 7.100 jtag_byte_1 <= rx_byte; 7.101 state <= `LM32_JTAG_STATE_READ_BYTE_2; 7.102 @@ -400,7 +392,7 @@ 7.103 end 7.104 `LM32_JTAG_STATE_READ_BYTE_2: 7.105 begin 7.106 - if (rx_toggle_r_r != rx_toggle_r_r_r) 7.107 + if ((~rx_update_r_r_r & rx_update_r_r) == `TRUE) 7.108 begin 7.109 jtag_byte_2 <= rx_byte; 7.110 state <= `LM32_JTAG_STATE_READ_BYTE_3; 7.111 @@ -408,7 +400,7 @@ 7.112 end 7.113 `LM32_JTAG_STATE_READ_BYTE_3: 7.114 begin 7.115 - if (rx_toggle_r_r != rx_toggle_r_r_r) 7.116 + if ((~rx_update_r_r_r & rx_update_r_r) == `TRUE) 7.117 begin 7.118 jtag_byte_3 <= rx_byte; 7.119 if (command == `LM32_DP_READ_MEMORY) 7.120 @@ -419,7 +411,7 @@ 7.121 end 7.122 `LM32_JTAG_STATE_READ_BYTE_4: 7.123 begin 7.124 - if (rx_toggle_r_r != rx_toggle_r_r_r) 7.125 + if ((~rx_update_r_r_r & rx_update_r_r) == `TRUE) 7.126 begin 7.127 jtag_byte_4 <= rx_byte; 7.128 state <= `LM32_JTAG_STATE_PROCESS_COMMAND;