here is a code for sequential multiplier. the issue with the code is that the output is not registered. How can i register the output

StackOverflow https://stackoverflow.com/questions/19399909

  •  30-06-2022
  •  | 
  •  

문제

module multiplier(//global inputs
          i_clk,i_rst,
          //outputs
          o_product,o_done,
          //input
          i_multiplicant,i_multiplier,i_start
          );

   //parameter declarations
   parameter MULTIPLICANT_WIDTH =5;       //width for multiplicant
   parameter MULTIPLIER_WIDTH =8;        //width for multiplier
   parameter TWOSCOMP=0;                  //'1'=signed multiplication and '0'=unsigned multiplication
   parameter PRODUCT_WIDTH =(MULTIPLICANT_WIDTH+MULTIPLIER_WIDTH);   //width of the product  
   parameter NPOWER = 6;                           //multiplier width<=2**NPOWER
   parameter NULL_VECTOR_S = 32'h00000000;       //used to fill the upper part of product register with zero at the begining of multiplication
   parameter S0= 2'd0;
   parameter S1= 2'd1;
   parameter S2= 2'd2;  


   //global inputs
   input i_clk;
   input i_rst;

   //outputs
   output [PRODUCT_WIDTH-1:0] o_product;
   output             o_done;

   //input
   input [MULTIPLICANT_WIDTH-1:0] i_multiplicant;
   input [MULTIPLIER_WIDTH-1:0]   i_multiplier;
   input              i_start;      //indicates start of multiplication

   // reg and wire declarations
   reg                o_done; 
   //  reg   [PRODUCT_WIDTH-1:0] o_product;
   reg                sign_i;      //sign product
   reg [PRODUCT_WIDTH-1:0]    product_i; 
   reg [PRODUCT_WIDTH-1:0]    product_ii;
   reg [NPOWER-1:0]           count_i;    
   reg [MULTIPLICANT_WIDTH-1:0]   multiplicant_i;
   reg [MULTIPLIER_WIDTH-1:0]     multiplier_i;
   reg                add_i;
   reg                shr_i;
   reg [1:0]              state=2'b00;
   reg [1:0]              nextstate=2'b00;

   //correcting the bits for signed multiplication   

   generate
      if(TWOSCOMP==1) 
    always@(i_multiplier,i_multiplicant)
      begin  
             $display("Testing signed numbers");
             multiplicant_i=rectify_multcnd(i_multiplicant,TWOSCOMP); 
         multiplier_i=rectify_mulplr(i_multiplier,TWOSCOMP);
      end 
   endgenerate 
   generate
      if(TWOSCOMP==0)
    always@(i_multiplicant,i_multiplier)
      begin
         $display("Testing unsigned numbers");
         multiplicant_i<=i_multiplicant;
         multiplier_i<=i_multiplier;
      end  
   endgenerate

   //functionn to correct multiplicant bits   
   function [MULTIPLICANT_WIDTH-1:0]rectify_multcnd;    
      input [MULTIPLICANT_WIDTH-1:0]multiplicant;
      reg [MULTIPLICANT_WIDTH-1:0]  rec_v;
      input                 twoc;
      begin
     if((multiplicant[MULTIPLICANT_WIDTH-1] & twoc)==1)
       rec_v=~(multiplicant);
     else
       rec_v=multiplicant;
     rectify_multcnd=(rec_v+(multiplicant[MULTIPLICANT_WIDTH-1] & twoc));
      end
   endfunction
   //function to correct multipier bits            
   function [MULTIPLIER_WIDTH-1:0]rectify_mulplr;   
      input [MULTIPLIER_WIDTH-1:0]multiplier;
      reg [MULTIPLIER_WIDTH-1:0]  rec_v;
      input               twoc;
      begin
     if((multiplier[MULTIPLIER_WIDTH-1] & twoc)==1)
       rec_v=~(multiplier);
     else
       rec_v=multiplier;
     rectify_mulplr=(rec_v+(multiplier[MULTIPLIER_WIDTH-1] & twoc));
      end
   endfunction     

   //start of multiplication  
   always@(posedge i_clk or posedge i_rst) 
     begin
    if(i_rst==1)
      product_i<=18'd0;
    else begin 
       if(i_start==1) begin 
          sign_i<= i_multiplicant[MULTIPLICANT_WIDTH-1] ^ i_multiplier[MULTIPLIER_WIDTH-1]; 
          product_i <= {NULL_VECTOR_S[MULTIPLICANT_WIDTH-1:0], multiplier_i}; 
       end  else if (add_i==1)
         product_i<= {{1'b0, product_i[PRODUCT_WIDTH-1:MULTIPLIER_WIDTH]} + {1'b0,multiplicant_i}, product_i[MULTIPLIER_WIDTH-1:1]};
       else if (shr_i==1)
         product_i<= {1'b0 , product_i[PRODUCT_WIDTH-1:1]};
    end 
     end // always@ (posedge i_clk or posedge i_rst or posedge i_start)

   //always block to transverse through the states   
   always@(posedge i_clk or posedge i_rst)
     begin
    if(i_rst==1)begin
       state<=S0;
       count_i<=0;
    end else begin
       state<=nextstate;
       if(state==S1) begin
          count_i<=count_i-1;   
       end 
       else if (state==S0)  begin 
          count_i<=(MULTIPLIER_WIDTH-1);
       end
    end 
     end // always@ (posedge i_clk or posedge i_rst)

   always@(state,i_start,product_i,count_i)
     begin                                
        case (state) 
          S0 :begin 
             add_i <= 0;
             shr_i <= 0;
             o_done <= 0;                                           
             if  (i_start==1) 
               nextstate <= S1; 
             else 
               nextstate <= S1;
      end 
          S1:begin
             o_done  <= 0;                                           
             add_i <= product_i[0]; 
             shr_i <= ~product_i[0];
             if (count_i==NULL_VECTOR_S [(NPOWER-1):0])
               nextstate <= S2 ; 
             else 
               nextstate <= S1;      
          end              
          S2 :begin  
             o_done  <= 1;                                           
             add_i <= 0;
             shr_i <= 0;
             nextstate <= S0;
      end 
      default:begin
             o_done  <= 0;                                           
             add_i <= 0;
             shr_i <= 0;                                           
             nextstate <= S0;
          end
    endcase // case (state)     
     end // always@ (state,i_start,product_i,count_i) 

 /*assigning the outputs according to the sign*/  
   generate
      if(TWOSCOMP==1)
    always@(state,i_start,product_i,count_i)
      begin 
         if(sign_i ==1)
           product_ii <=((~(product_i)) + 1); 
         else
           product_ii<=product_i;
      end  
   endgenerate 

   generate
      if(TWOSCOMP==0)
    always@(state,i_start,product_i,count_i)
      begin 
         product_ii<=product_i;
      end
   endgenerate 

   assign o_product= product_ii;          
endmodule // multiplier

This is the main module for which we get the output. Can some one tell me how to register the output.

도움이 되었습니까?

해결책

lets assume the unregistered output is called out_unreg:

output reg out;

always @(posedge i_clk or posedge i_rst)
   if (i_rst)
      out <= 0;
   else
      out <= out_unreg;

out is the registered version of out_unreg. It's clocked by i_clk and reset to 0 by i_rst; both on rising edge.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top