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
  •  | 
  •  

Domanda

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.

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top