0
\$\begingroup\$

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
\$\endgroup\$
1
  • \$\begingroup\$ Probably you should make next_state a combinatorial output, not another register. \$\endgroup\$
    – HKOB
    May 23, 2019 at 4:35

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$
3
  • \$\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
    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, like vga_plot. \$\endgroup\$
    – dave_59
    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
    May 23, 2019 at 21:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.