for some reason there is a delay in when the next_state is evaluated. To my understanding it should be updated on the same rising clock as when state is updated. Could someone please help me explain why this is occurring and how to fix it?
module circle(input logic clk, input logic rst_n, input logic [2:0] colour,
input logic [7:0] centre_x, input logic [6:0] centre_y, input logic [7:0] radius,
input logic start, output logic done,
output logic [7:0] vga_x, output logic [6:0] vga_y,
output logic [2:0] vga_colour, output logic vga_plot);
// draw the circle
enum logic [3:0] {Initialize = 4'b0000, Pixel1= 4'b0001, Pixel2 = 4'b0010, Pixel3 = 4'b0011, Pixel4 = 4'b0100, Pixel5 = 4'b0101, Pixel6 = 4'b0110, Pixel7 = 4'b0111, Pixel8 = 4'b1000, Compare = 4'b1001} state, next_state;
logic [7:0] offset_x, offset_y;
logic signed [9:0] crit;
always @ (posedge clk) begin
case(state)
Initialize: begin
if (start == 1)
next_state <= Pixel1;
else begin
next_state <= Initialize; end
offset_y <= 0;
offset_x <= radius;
crit <= 1-radius;
end
Pixel1: begin
if (offset_y < offset_x) begin
vga_x <= centre_x + offset_x;
vga_y <= centre_y + offset_y; end
next_state <= Pixel2;
vga_plot <= 1;
vga_colour <= colour;
end
Pixel2: begin
if (offset_y < offset_x) begin
vga_x <= centre_x + offset_y;
vga_y <= centre_y + offset_x; end
next_state <= Pixel3;
vga_plot <= 1;
vga_colour <= colour;
end
Pixel3: begin
if (offset_y < offset_x) begin
vga_x <= centre_x - offset_y;
vga_y <= centre_y + offset_x; end
next_state <= Pixel4;
vga_plot <= 1;
vga_colour <= colour;
end
Pixel4: begin
if (offset_y < offset_x) begin
vga_x <= centre_x - offset_x;
vga_y <= centre_y + offset_y; end
next_state <= Pixel5;
vga_plot <= 1;
vga_colour <= colour;
end
Pixel5: begin
if (offset_y < offset_x) begin
vga_x <= centre_x - offset_x;
vga_y <= centre_y - offset_y; end
next_state <= Pixel6;
vga_plot <= 1;
vga_colour <= colour;
end
Pixel6: begin
if (offset_y < offset_x) begin
vga_x <= centre_x - offset_y;
vga_y <= centre_y - offset_x; end
next_state <= Pixel7;
vga_colour <= colour;
end
Pixel7: begin
if (offset_y < offset_x) begin
vga_x <= centre_x + offset_x;
vga_y <= centre_y - offset_y; end
next_state <= Pixel8;
vga_plot <= 1;
vga_colour <= colour;
end
Pixel8: begin
if (offset_y < offset_x) begin
vga_x <= centre_x + offset_y;
vga_y <= centre_y - offset_x; end
next_state <= Compare;
vga_plot <= 1;
vga_colour <= colour;
end
Compare: begin
offset_y = offset_y + 1;
if (crit <= 0)
crit = crit + 2 * offset_y +1;
else begin
offset_x = offset_x -1;
crit = crit + 2 * (offset_y - offset_x) + 1; end
next_state <= Initialize;
end
default: next_state <= Pixel1;
endcase
end
always_ff @ (posedge clk) begin
if (rst_n == 0)
state <= Initialize;
else
state <= next_state;
end
endmodule
-
\$\begingroup\$ Probably you should make next_state a combinatorial output, not another register. \$\endgroup\$HKOB– HKOB2019年05月23日 04:35:26 +00:00Commented May 23, 2019 at 4:35
1 Answer 1
When you say "there is a delay", I assume you mean there is 1 clock cycle delay in the state assignment from what you expect it to be.
If you are trying to code a Mealy FSM, then change the first always @(posed clk
block to always_comb
and remove all the non-blocking assignments <=
to =
. For a Moore FSM, just assign directly to state
and get rid of the intermediate next_state
.
-
\$\begingroup\$ Thanks so much, I understand now. I had a question about multiple outputs. If there a way of clumping the outputs in an array or something to avoid having to list each output for each case? \$\endgroup\$James Dean– James Dean2019年05月23日 05:06:56 +00:00Commented May 23, 2019 at 5:06
-
\$\begingroup\$ Not exactly sure what you mean, you probably should ask ass a separate question. But you could move some output assignments outside the
case
if they are repetitive, likevga_plot
. \$\endgroup\$dave_59– dave_592019年05月23日 14:23:43 +00:00Commented May 23, 2019 at 14:23 -
\$\begingroup\$ You need to as this is a new question with the latest version of your code \$\endgroup\$dave_59– dave_592019年05月23日 21:07:23 +00:00Commented May 23, 2019 at 21:07