- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Tags:
- cycloneV
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you indicate where on your Signal Tap pictures you are getting unexpected behavior?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
fail.jpg transition 146
fail2.jpg transition 316
fail3.jpg transition 1026
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't see any issues in the code, so it must be something else. Is your design meeting timing? Do you have a complete .sdc file for the design?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are all your inputs registered to the clock?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Inputs are input pins without any clock.
Assigning them to registers (with 1 clock period delay, but it does not matter as input is much slower than clock) solved the problem.
cur_A <= sensor_A;
cur_B <= sensor_B;
cur_X <= sensor_X;

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page