Nikolai
New Contributor
4 years agoverilog register gets corrupted
Im trying to interface quadrature encoder with Terasic SoM eval board but got strange behaviour.
All works fine for a short while, but after it registers holding position/rotation became corrupted. Depending on rearragning same code in verilog file and speed of rotation only rotation register or both became corrupted. I've spent a few days trying to figure out what's wrong but without any success. Is there something I've missed? Behaviour is exaclty the same on two boards.
Verilog file with interface, signal tap images and full project attached.
module cui_amt ( clk, reset_n, sensor_A, sensor_B, sensor_X, // Avalon slave read, write, address, readdata, writedata ); parameter PPR = 8192; input clk; input reset_n; input sensor_A; input sensor_B; input sensor_X; reg [31:0] position = 0; reg [31:0] rotation = 0; reg sync_lost; reg got_zero; // Avalon slave // 0 - posiion // 1 - rotation // 2 - status // 0 - sync_lost // 1 - got zero // 3 - control // 1 - reset input read; input write; input [1:0] address; output [31:0] readdata; input [31:0] writedata; reg prev_A; reg prev_B; reg prev_X; always @(posedge clk) begin if (reset_n) begin if (read) begin case (address) 0: begin readdata <= position; end 1: begin readdata <= rotation; end 2: begin readdata[0] <= sync_lost; readdata[1] <= got_zero; readdata[31:2] <= 0; end endcase end if (write && writedata == 1) // Reset command begin position <= 0; rotation <= 0; sync_lost <= 0; got_zero <= 0; end else begin // Quadrature // A 110011 // B 011001 if (sensor_X) begin got_zero <= 1; end if (sensor_A != prev_A || sensor_B != prev_B) begin if (prev_A == sensor_A) begin if ((prev_A == 1 && prev_B == 0) || (prev_A == 0 && prev_B == 1)) begin position <= position - 1; rotation <= rotation != 0 ? (rotation - 1) : (PPR - 1); end else begin position <= position + 1; rotation <= rotation != (PPR - 1) ? (rotation + 1) : 0; end prev_B <= sensor_B; end else if (prev_B == sensor_B) begin if ((prev_B == 1 && prev_A == 1) || (prev_B == 0 && prev_A == 0)) begin position <= position - 1; rotation <= rotation != 0 ? (rotation - 1) : (PPR - 1); end else begin position <= position + 1; rotation <= rotation != (PPR - 1) ? (rotation + 1) : 0; end prev_A <= sensor_A; end else begin prev_A <= sensor_A; prev_B <= sensor_B; sync_lost <= 1; end end end end else begin position <= 0; rotation <= 0; sync_lost <= 0; got_zero <= 0; prev_A <= sensor_A; prev_B <= sensor_B; end end endmodule
Are all your inputs registered to the clock?