Advertisement
Harmony5757

Shift-Add Multiplier

Jun 14th, 2025
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
SystemVerilog 8.06 KB | Source Code | 0 0
  1. //============================
  2. // Top Module
  3. //============================
  4.  
  5. `timescale 1ns / 1ps
  6. //Shift-Add Mplier
  7. //Checks Mplier bit [0] => If 1 => Add Mcand to Accumulator,
  8. //                         If 0 => Skip
  9. //Right Shift Mplier, Left Shift Mcand
  10. //Repeat Until all Mplier Bits have been checked.
  11. module ShiftAdd_Mplier #(parameter WIDTH = 2)
  12.     (
  13.     input logic clk, srst, Mul_Start,
  14.     input logic [WIDTH - 1 : 0] Mplier, Mcand,
  15.     output logic [2*WIDTH - 1 : 0] Product,
  16.     output logic Done
  17.     );
  18.     logic Acc_en, R_Shift, L_Shift, R_Shift_Done, L_Shift_Done, Acc_Done;
  19.    
  20.     logic int_srst; //internal reset for Accumulator
  21.    
  22.     logic [$clog2(WIDTH + 1) - 1:0] Mplier_Bit_Count;
  23.     logic [2*WIDTH - 1 : 0] temp_Mcand; logic [WIDTH - 1 : 0] temp_Mplier;
  24.     logic [2*WIDTH - 1: 0] Acc_Out, temp_Sum;
  25.     logic [WIDTH - 1 : 0] temp_reg1;
  26.     logic [2*WIDTH - 1: 0] temp_reg2;
  27.    
  28.     Shifter #(.WIDTH(WIDTH)) R_Shifter(
  29.                                            .clk(clk),
  30.                                            .srst(srst),
  31.                                            .R_Shift(R_Shift),
  32.                                            .L_Shift(0),
  33.                                            .In(temp_Mplier),
  34.                                            .Shifter_Out(temp_reg1),
  35.                                            .Shift_Done(R_Shift_Done)
  36.                                            );
  37.                                            
  38.     Shifter #(.WIDTH(2*WIDTH)) L_Shifter(
  39.                                            .clk(clk),
  40.                                            .srst(srst),
  41.                                            .R_Shift(0),
  42.                                            .L_Shift(L_Shift),
  43.                                            .In(temp_Mcand),
  44.                                            .Shifter_Out(temp_reg2),
  45.                                            .Shift_Done(L_Shift_Done)
  46.                                            );
  47.                                      
  48.     Carry_LookAhead #(.WIDTH(2*WIDTH)) CLA(    .clk(clk),
  49.                                                .srst(srst),
  50.                                                .A(temp_Mcand),
  51.                                                .B(Acc_Out),
  52.                                                .Cin(0),
  53.                                                .Sum(temp_Sum)
  54.                                                );
  55.                                                
  56.     Accumulator #(.WIDTH(2*WIDTH)) Acc(
  57.                                          .clk(clk),
  58.                                          .srst(int_srst),
  59.                                          .Acc_en(Acc_en),
  60.                                          .Acc_In(temp_Sum),
  61.                                          .Acc_Out(Acc_Out),
  62.                                          .Acc_Done(Acc_Done)
  63.                                          );
  64.                                        
  65.    
  66.     always_ff @(posedge clk) begin
  67.         if (srst) begin
  68.             temp_Mcand      <= 0;
  69.             temp_Mplier     <= 0;
  70.             Product         <= 0;
  71.             Mplier_Bit_Count<= 0;
  72.             Done            <= 0;
  73.             L_Shift         <= 0;
  74.             R_Shift         <= 0;
  75.             Acc_en          <= 0;
  76.             int_srst        <= 1;
  77.         end
  78.         else if (!L_Shift && !R_Shift && !Acc_en) begin //if not performing Shifting or accumulating Operations
  79.             if (Mul_Start) begin
  80.                 temp_Mcand             <= {{WIDTH{1'b0}}, Mcand};
  81.                 temp_Mplier            <= Mplier;
  82.                 Mplier_Bit_Count       <= WIDTH;
  83.                 Done                   <= 0;
  84.                 L_Shift                <= 0;
  85.                 R_Shift                <= 0;
  86.                 Acc_en                 <= 0;
  87.                 int_srst               <= 1;
  88.             end
  89.             else if (Mplier_Bit_Count != 0) begin
  90.                 int_srst         <= 0;
  91.                 L_Shift          <= 1;
  92.                 R_Shift          <= 1;
  93.                 Mplier_Bit_Count <= Mplier_Bit_Count - 1;
  94.                 if (temp_Mplier[0]) begin
  95.                     Acc_en <= 1;
  96.                 end
  97.                 if (Mplier_Bit_Count == WIDTH - 1) begin
  98.                     Done <= 1;
  99.                 end    
  100.             end
  101.             if (Done) begin
  102.                 Product <= Acc_Out[2*WIDTH - 1 : 0];
  103.             end
  104.         end
  105.         else begin
  106.             if (L_Shift) begin
  107.                 if (L_Shift_Done) begin
  108.                     L_Shift    <= 0;
  109.                     temp_Mcand <= temp_reg2;
  110.                 end
  111.             end
  112.             if (R_Shift) begin
  113.                 if (R_Shift_Done) begin
  114.                     R_Shift     <= 0;
  115.                     temp_Mplier <= temp_reg1;
  116.                 end
  117.             end
  118.             if (Acc_en) begin
  119.                 if (Acc_Done) begin
  120.                     Acc_en <= 0;
  121.                 end
  122.             end
  123.         end
  124.     end
  125. endmodule
  126.  
  127. //============================
  128. // Shifter Module
  129. //============================
  130.  
  131. `timescale 1ns / 1ps
  132. module Shifter #(parameter WIDTH = 4)
  133.     (
  134.     input logic clk, srst, R_Shift, L_Shift,
  135.     input logic [WIDTH - 1 : 0] In,
  136.     output logic [WIDTH - 1 : 0] Shifter_Out,
  137.     output logic Shift_Done
  138.     );
  139.    
  140.     always_ff @(posedge clk) begin
  141.         if (srst) begin
  142.             Shifter_Out <= 0;
  143.             Shift_Done <= 0;
  144.         end
  145.         else if (R_Shift) begin
  146.             Shifter_Out <= In >> 1;
  147.             Shift_Done <= 1;
  148.         end
  149.         else if (L_Shift) begin
  150.             Shifter_Out <= In << 1;
  151.             Shift_Done <= 1;
  152.         end
  153.         else if (!L_Shift || !R_Shift) begin
  154.             Shift_Done <= 0;
  155.         end
  156.     end
  157. endmodule
  158.  
  159. //============================
  160. // Carry Lookahead Adder Module
  161. //============================
  162.  
  163. `timescale 1ns / 1ps
  164. module Carry_LookAhead #(parameter WIDTH = 4)
  165.     (
  166.     input logic [WIDTH - 1:0] A, B,
  167.     input logic Cin, clk, srst,
  168.     output logic [WIDTH - 1:0] Sum,
  169.     output logic Cout
  170.     );
  171.     logic [WIDTH - 1:0] Gen, Prop, temp_Sum; logic [WIDTH:0] Carry_in;
  172.    
  173.     assign Carry_in[0] = Cin;
  174.     genvar i;
  175.     generate
  176.         for( i = 0; i < WIDTH; i++) begin : LookAhead
  177.             Full_Adder Full_Adder_inst
  178.                 (
  179.                     .A(A[i]),
  180.                     .B(B[i]),
  181.                     .Cin(Carry_in[i]),
  182.                     .Sum(temp_Sum[i]),
  183.                     .Cout()
  184.                     );
  185.         end
  186.     endgenerate
  187.    
  188.     genvar j;
  189.     generate
  190.         for( j = 0; j < WIDTH; j++) begin
  191.             assign Gen[j] = A[j] & B[j];
  192.             assign Prop[j] = A[j] | B[j];
  193.             assign Carry_in[j+1] = Gen[j] | (Prop[j] & Carry_in[j]);
  194.         end
  195.     endgenerate
  196.     always_ff @(posedge clk) begin
  197.         if (srst) begin
  198.             Sum <= 0;
  199.             Cout <= 0;
  200.         end
  201.         else begin
  202.             Sum <= temp_Sum;
  203.             Cout <= Carry_in[WIDTH];
  204.         end
  205.     end  
  206. endmodule
  207.  
  208. `timescale 1ns / 1ps
  209. //==================================================
  210. //FULL ADDER Implementation
  211. //==================================================
  212. module Full_Adder(
  213.     input logic A,
  214.     input logic B,
  215.     input logic Cin,
  216.     output logic Sum,
  217.     output logic Cout
  218.     );
  219.    
  220.     assign Sum = A ^ B ^ Cin;
  221.     assign Cout = A&B | A&Cin | B&Cin;
  222. endmodule
  223.  
  224.  
  225. //============================
  226. // Accumulator Module
  227. //============================
  228.  
  229. `timescale 1ns / 1ps
  230. module Accumulator #(parameter WIDTH = 4)
  231.     (
  232.     input logic clk, srst, Acc_en,
  233.     input logic [WIDTH - 1 : 0] Acc_In,
  234.     output logic [WIDTH - 1: 0] Acc_Out,
  235.     output logic Acc_Done
  236.     );
  237.    
  238.     always_ff @(posedge clk) begin
  239.         if (srst) begin
  240.             Acc_Out <= 0;
  241.         end
  242.         else if (Acc_en) begin
  243.             Acc_Out <= Acc_In;
  244.             Acc_Done <= 1;
  245.         end
  246.         else if (!Acc_en) begin
  247.             Acc_Done <= 0;
  248.         end
  249.     end
  250.    
  251. endmodule
  252.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement