1
\$\begingroup\$

I am new to the world of HDL. I am currently working on implementing AES in Verilog code.

I manage the flow of my logic using varying FSMs. Given this approach I currently have to wait for the first block to finish processing before inputting the next one.

To improve throughput, I want to perform pipelining so I can input a new block every N clock cycles. However, I can't fathom how I would use both FSM and pipelining. Given I use a register to track the current state, if I pass a new input in this will overwrite the state for the previous input.

Is it possible to use an FSM and pipelining in unison?

Given the below code, I cannot generate a new output every clock cycle. This is because the second input cannot go through the FSM before until the first completes. This is a simplified example of what I am trying to achieve.

`timescale 1ns / 1ps

module pipeline_multiplier(
    input [15:0] a,
    input [15:0] b,
    input clk,
    input rst,
    output reg [31:0] c
    );
    
    reg [15:0] a_temp, b_temp;
    reg [31:0] c_temp;
    
    parameter [1:0] 
        Pipe1=2'b00, 
        Pipe2=2'b01, 
        Pipe3=2'b10;
    reg [1:0] state = Pipe1;
    
    always @(posedge clk)
    begin
        if(rst)
        begin
            state = Pipe1;            
        end
        else
        begin
            case(state)
                Pipe1:
                begin
                    a_temp <= a;
                    b_temp <= b;
                    state <= Pipe2;
                end
                Pipe2:
                begin
                    c_temp <= a_temp * b_temp;
                    state <= Pipe3;
                end
                Pipe3:
                begin
                    c <= c_temp;
                    state <= Pipe1;
                end
            endcase
        end
    end
   
    
endmodule

\$\endgroup\$
2
  • 3
    \$\begingroup\$ I am new to the world of HDL. The world of HDL welcomes you! "I am currently working on implementing AES in Verilog code.* Now, that is a deep end of a pool to learn swimming. \$\endgroup\$ Commented Jun 27, 2021 at 12:22
  • 1
    \$\begingroup\$ Why do you try to fit in the FSM, while your problem statement doesn't need one at all. This looks like XY problem. \$\endgroup\$
    – Mitu Raj
    Commented Jun 27, 2021 at 12:28

2 Answers 2

1
\$\begingroup\$

Yes, it is possible to use an FSM and pipelining "in unison". This is how the instruction execution pipelines on processors are controlled. An FSM of some fashion is needed for situations such as branching, where the pipeline may need to be flushed.

\$\endgroup\$
4
  • \$\begingroup\$ Hi Elliot, Thanks for your feedback, I have provided an example code of what I am trying to achieve. How do I maintain the state register when passing in multiple inputs? \$\endgroup\$ Commented Jun 27, 2021 at 11:39
  • \$\begingroup\$ @ChrisMcNeill generally we use an explicit FSM only to control the pipeline. \$\endgroup\$ Commented Jun 27, 2021 at 12:08
  • \$\begingroup\$ @ChrisMcNeill at each cycle you can keep incrementing a register that points to the pipeline stage \$\endgroup\$ Commented Jun 27, 2021 at 12:10
  • 1
    \$\begingroup\$ @ChrisMcNeill Your example code is trivial...it doesn't need an FSM at all. Get rid of the case statement and just combine all of the register assignments into a single clocked always block. \$\endgroup\$ Commented Jun 27, 2021 at 13:00
0
\$\begingroup\$

Good luck with learning verilog :). This seems like a simple multiplier and doesn't seem to require an FSM. I would code the module this way which will implicitly be pipelined. Also, I wouldn't registers the inputs as they will be flopped (registered) in the previous module of the AES pipeline.

`timescale 1ns / 1ps

module pipeline_multiplier(
input [15:0] a,
input [15:0] b,
input clk,
input rst,
output reg [31:0] c
);

reg [15:0] a_temp, b_temp;
reg [31:0] c_temp; // not needed as c is already a register 

always @(posedge clk)
begin
    if(rst)
    begin
        a_temp <= 16'd0;
        b_temp <= 16'd0;
        c <= 16'd0;
    end
    else
    begin
         a_temp <= a;  // This isn't typically done as inputs are registered 
                       // in previous module of the pipeline
         b_temp <= b;
         c <= a_temp * b_temp;
    end
end


endmodule
\$\endgroup\$

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.