How to write a signed number in verilog?

230 Views Asked by At

I want to write a verilog code that outputs the Sum of 2 8 bits 2's complement signed integers. Another binary output signal, called E, is raised HIGH when there is an overflow or underflow in the final result.

But when my test bench is in negative (signed) it becomes an unsigned int.

for ex, (-23)base 10 signed (11101001)base 2 signed, becomes (233)base 10 (11101001)base 2 unsigned.

//ripple_adder.v
module Full_Adder (A, B, carry_in, sum, carry_out);
    input signed A, B;
    input signed carry_in;
    output signed sum;
    output carry_out;

    assign sum = (A^B^carry_in);
    assign carry_out = ((A&B) | (B&carry_in) | (carry_in&A));
endmodule

module ripple_adder (A, B, carry_in, sum, carry_out, E);
    input signed [7:0] A;
    input signed [7:0] B;
    input carry_in;
    output signed [7:0] sum;
    output carry_out;
    output E;
    wire [6:0] carry;

    Full_Adder FA0(A[0], B[0], carry_in, sum[0], carry[0]);
    Full_Adder FA1(A[1], B[1], carry_in, sum[1], carry[1]);
    Full_Adder FA2(A[2], B[2], carry_in, sum[2], carry[2]);
    Full_Adder FA3(A[3], B[3], carry_in, sum[3], carry[3]);
    Full_Adder FA4(A[4], B[4], carry_in, sum[4], carry[4]);
    Full_Adder FA5(A[5], B[5], carry_in, sum[5], carry[5]);
    Full_Adder FA6(A[6], B[6], carry_in, sum[6], carry[6]);
    Full_Adder FA7(A[7], B[7], carry_in, sum[7], carry_out);

    assign E = ((carry_out & ~carry[6]) | (~carry_out & carry[6]));

endmodule
//ripple_adder_tb.v
// testbench module
`timescale 1ps/1ps
`include "coba.v"

module cobatb;
  reg signed [7:0] A, B;
  reg carry_in;
  wire signed [7:0] S;
  wire carry_out;
  wire E;

  ripple_adder uut (
    .A(A),
    .B(B),
    .carry_in(carry_in),
    .sum(S),
    .carry_out(carry_out),
    .E(E)
  );

  initial begin
    $dumpfile("cobatb.vcd");
    $dumpvars(0, cobatb);

    // Test 1
    A = 5;
    B = 10;
    carry_in = 0;
    #10;

    // Test 2
    A = 87;
    B = -23;
    carry_in = 0;
    #10;

    // Test 3
    A = -120;
    B = 60;
    carry_in = 0;
    #10

    // Test 4
    A = -80;
    B = -64;
    carry_in = 0;
    #10

    // Additional tests...
    $display("Test is complete");
    $finish;
  end
endmodule

How to put a signed 2's complement integer in verilog testbench

1

There are 1 best solutions below

2
On

How to write a signed number in Verilog?

  • To create literals explicitly as signed, use the pattern
    <size>’<signed><radix>value
    (”<>” indicates optional part)
    Either s or S can be used for the <signed> field Use these for the field
’b or ’B : binary
’o or ’O : octal
’h or ’H : hex
’d or ’D : decimal

Use: -8'sd23; to represent minus twenty three decimal as an eight bit signed number.

-23 is working fine in your code (see below where the numbers are printed) to represent a negative decimal number, and looks easier to read and write than -8'sd23;

  • Lets $display() the B variable to see how verilog is interpreting B.
    // Test 1
    A = 5;
    B = 10;
    carry_in = 0;
    $display("B = %0d",B);
    #10;

    // Test 2
    A = 87;
    B = -23;
    carry_in = 0;
    $display("B = %0d",B);
    #10;

    // Test 3
    A = -120;
    B = 60;
    carry_in = 0;
    $display("B = %0d",B);
    #10

    // Test 4
    A = -80;
    B = -64;
    carry_in = 0;
    $display("B = %0d",B);
    #10

It produces this output in different simulators.

B = 10
B = -23
B = 60
B = -64
Test is complete

Verilog is picking up the negative values.
Verilog is treating the testbech bit vectors as signed (2's complement), which is expected because they are declared as signed.

  • Its possible that you are looking at a waveform viewer and its showing you an unsigned interpretation of the bit pattern. Some waveform viewers have an option to show vector bit patterns as a signed decimal value. If you are seeing an unsigned value in waves, look for the signed option in the waveform viewer menus or toolbar buttons.