Advertisement
Guest User

Signed integer Source code

a guest
May 25th, 2024
66
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
SystemVerilog 3.42 KB | Source Code | 1 0
  1. `timescale 1ns / 1ps
  2. module div #(
  3.     parameter int unsigned DATA_WIDTH = 32
  4. ) (
  5.     input logic clk,
  6.     input logic rst_n,
  7.     input logic [DATA_WIDTH-1:0] dividend,
  8.     input logic [DATA_WIDTH-1:0] divisor,
  9.     input logic signed_ope,
  10.     input logic start,
  11.     input logic flush,
  12.     output logic [DATA_WIDTH-1:0] quotient,
  13.     output logic [DATA_WIDTH-1:0] remainder,
  14.     output logic ready
  15. );
  16.   localparam int unsigned D1 = 1;
  17.   localparam int unsigned COUNT_WIDTH = $clog2(DATA_WIDTH + 1);
  18.  
  19.   logic r_ready;
  20.   logic r_signed_ope;
  21.   logic [COUNT_WIDTH-1:0] r_count;
  22.   logic [DATA_WIDTH-1:0] r_quotient;
  23.   logic w_dividend_sign;
  24.   logic r_dividend_sign;
  25.   logic remainder_sign;
  26.   logic [DATA_WIDTH:0] r_remainder;
  27.   logic [DATA_WIDTH-1:0] r_divisor;
  28.   logic [DATA_WIDTH:0] divisor_ext;
  29.   logic divisor_sign;
  30.   logic [DATA_WIDTH:0] rem_quo;
  31.   logic                diff_sign;
  32.   logic [DATA_WIDTH:0] sub_add;
  33.  
  34.   assign ready = r_ready;
  35.  
  36.   assign divisor_sign = r_divisor[DATA_WIDTH-1] & r_signed_ope;
  37.   assign divisor_ext = {divisor_sign, r_divisor};
  38.   assign remainder_sign = r_remainder[DATA_WIDTH];
  39.  
  40.   assign rem_quo = {r_remainder[DATA_WIDTH-1:0], r_quotient[DATA_WIDTH-1]};
  41.   assign diff_sign = remainder_sign ^ divisor_sign;
  42.   assign sub_add = diff_sign ? rem_quo + divisor_ext :
  43.                                rem_quo - divisor_ext;
  44.  
  45.   // after process
  46.   always_comb begin
  47.     quotient  = (r_quotient << 1) | 1;
  48.     remainder = r_remainder[DATA_WIDTH-1:0];
  49.  
  50.     if (r_remainder == 0) begin
  51.       // do nothing
  52.     end else if (r_remainder == divisor_ext) begin
  53.       quotient  = quotient + 1;
  54.       remainder = remainder - r_divisor;
  55.     end else if (r_remainder == -divisor_ext) begin
  56.       quotient  = quotient - 1;
  57.       remainder = remainder + r_divisor;
  58.     end else if (remainder_sign ^ r_dividend_sign) begin
  59.       if (diff_sign) begin
  60.         quotient  = quotient - 1;
  61.         remainder = remainder + r_divisor;
  62.       end else begin
  63.         quotient  = quotient + 1;
  64.         remainder = remainder - r_divisor;
  65.       end
  66.     end
  67.   end
  68.  
  69.   assign w_dividend_sign = dividend[DATA_WIDTH-1] & signed_ope;
  70.  
  71.   always @(posedge clk or negedge rst_n) begin
  72.     if (~rst_n) begin
  73.       r_quotient      <= #D1 '0;
  74.       r_dividend_sign <= #D1 '0;
  75.       r_remainder     <= #D1 '0;
  76.       r_divisor       <= #D1 '0;
  77.       r_count         <= #D1 '0;
  78.       r_ready         <= #D1 1'b1;
  79.       r_signed_ope    <= #D1 1'b0;
  80.     end else begin
  81.       if (flush) begin
  82.         r_count         <= #D1 '0;
  83.         r_ready         <= #D1 1'b1;
  84.       end else if (start) begin
  85.         // RISC-V's div by 0 spec
  86.         if (divisor == '0) begin
  87.             r_quotient  <= #D1 '1;
  88.             r_remainder <= #D1 {w_dividend_sign, dividend};
  89.         end else begin
  90.             r_quotient  <= #D1 dividend;
  91.             r_remainder <= #D1 {(DATA_WIDTH+1){w_dividend_sign}};
  92.             r_ready     <= #D1 1'b0;
  93.         end
  94.         r_count         <= #D1 '0;
  95.         r_dividend_sign <= #D1 w_dividend_sign;
  96.         r_divisor       <= #D1 divisor;
  97.         r_signed_ope    <= #D1 signed_ope;
  98.       end else if (~ready) begin
  99.         r_quotient  <= #D1 {r_quotient[DATA_WIDTH-2:0], ~diff_sign};
  100.         r_remainder <= #D1 sub_add[DATA_WIDTH:0];
  101.         r_count     <= #D1 r_count + 1;
  102.         if (r_count == DATA_WIDTH - 1) begin
  103.           r_ready <= #D1 1'b1;
  104.         end
  105.       end
  106.     end
  107.   end
  108. endmodule
  109.  
  110.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement