Data Path synthesis Verilog(controlling bit-widths with signed quantities) 
Author Message
 Data Path synthesis Verilog(controlling bit-widths with signed quantities)

We are a company developing tools for synthesizing RTL VHDL/
Verilog from Matlab/Simulink descriptions of systems. Our
focus is on mapping the problems to the Platform FPGAs out
there like Virtex2, Excalibur/Yeager, QuickDSP etc.

We used the signed and unsigned data types from the numeric_std
VHDL library to generate the VHDL data-paths with tight bit-width
control. However for Verilog I could not find an equivalent.
Signed quantities are represented via integer which have a
fixed bit-width of 32. I know that the Verilog-2001 standard
is proposing something in this regard but it will be years till
the synthesis vendors will support these features.

My question is: How do designers creating data-path intensive
designs using Verilog, specially if the design has to support
signed operands using 2's compliment arithematic.

I would appreciate if you could point me to some code/books/
notes which can show examples of how things are being tackled.
Perhaps the code for a filter structure?



Sat, 08 May 2004 09:44:39 GMT  
 Data Path synthesis Verilog(controlling bit-widths with signed quantities)

Quote:

> We are a company developing tools for synthesizing RTL VHDL/
> Verilog from Matlab/Simulink descriptions of systems. Our
> focus is on mapping the problems to the Platform FPGAs out
> there like Virtex2, Excalibur/Yeager, QuickDSP etc.

> We used the signed and unsigned data types from the numeric_std
> VHDL library to generate the VHDL data-paths with tight bit-width
> control. However for Verilog I could not find an equivalent.
> Signed quantities are represented via integer which have a
> fixed bit-width of 32. I know that the Verilog-2001 standard
> is proposing something in this regard but it will be years till
> the synthesis vendors will support these features.

> My question is: How do designers creating data-path intensive
> designs using Verilog, specially if the design has to support
> signed operands using 2's compliment arithematic.

Basically, regs are unsigned, integers are signed.  Integers default to
32 bits wide, unless you constrain them otherwise.  regs default to one
bit wide, unless you constrain them otherwise.

-a



Sun, 09 May 2004 01:45:01 GMT  
 Data Path synthesis Verilog(controlling bit-widths with signed quantities)

Quote:
> Basically, regs are unsigned, integers are signed.  Integers default to
> 32 bits wide, unless you constrain them otherwise.  regs default to one
> bit wide, unless you constrain them otherwise.

What I wanted to get a handle on was on how to constrain
integers? Is the constraint achieved during the declaration
of the integer or does the synthesis tool understand the
range by the way the integers are used?

How do a model a signed value which has more than 32 bits?
The idea here is to be able to perform 2's compliment's
operations on these variables. For example, if I am adding
two 32 bit signed values I need at least 33 bits to model
the result (detect the overflow). I can achieve this by
using the signed and unsigned data types in VHDL (numeric_std).
Is therea convenient way of doing this in Verilog without having
to do explicit 2's complement transformation in the RTL code



Sun, 09 May 2004 11:36:05 GMT  
 Data Path synthesis Verilog(controlling bit-widths with signed quantities)

Quote:

> What I wanted to get a handle on was on how to constrain
> integers? Is the constraint achieved during the declaration
> of the integer or does the synthesis tool understand the
> range by the way the integers are used?

> How do a model a signed value which has more than 32 bits?
> The idea here is to be able to perform 2's compliment's
> operations on these variables. For example, if I am adding
> two 32 bit signed values I need at least 33 bits to model
> the result (detect the overflow). I can achieve this by
> using the signed and unsigned data types in VHDL (numeric_std).
> Is therea convenient way of doing this in Verilog without having
> to do explicit 2's complement transformation in the RTL code

I think this is only possible with the new signed data type defined in
Verilog 2000.  Some tools already support them, so you might want to
give it a try.  But be careful, arithmetic types have been defined in
Verilog 2000 in the most unlogical way.  Whenever signed and unsigned
vectors are mixed in an expression, everything becomes unsigned, which
is obviously wrong for signed vectors (the only meaningful conversion is
from unsigned to signed with a 1-bit zero-extension, as done in VHDL's
numeric_std).  Also, part-selects of signed vectors become unsigned,
even if part-select specifies the whole vector.  Example:

  reg signed [15:0] a;
  reg signed [7:0]  b;

  a = b;        // b is signed and therefore sign-extended
  a = b[7:0];   // b[7:0] is unsigned and therefore zero-extended

This severely limits the usefulness of signed types in Verilog again.

Reto



Mon, 10 May 2004 02:08:52 GMT  
 Data Path synthesis Verilog(controlling bit-widths with signed quantities)

Quote:
> I think this is only possible with the new signed data type defined in
> Verilog 2000.  Some tools already support them, so you might want to
> give it a try.  But be careful, arithmetic types have been defined in
> Verilog 2000 in the most unlogical way.  Whenever signed and unsigned
> vectors are mixed in an expression, everything becomes unsigned, which
> is obviously wrong for signed vectors (the only meaningful conversion is
> from unsigned to signed with a 1-bit zero-extension, as done in VHDL's
> numeric_std).  Also, part-selects of signed vectors become unsigned,
> even if part-select specifies the whole vector.  Example:

>   reg signed [15:0] a;
>   reg signed [7:0]  b;

>   a = b;        // b is signed and therefore sign-extended
>   a = b[7:0];   // b[7:0] is unsigned and therefore zero-extended

> This severely limits the usefulness of signed types in Verilog again.

Well my way is probably extremely retarded, but I couldn't think of any
other easy way.

Basically, whenever I need to do (simple) arithmetic on signed 2's C
data types, I converted the input values (from input ports) into
integers.

So far, this works in Verilog-XL, NC-Verilog.  Synthesis-output from
Synopsys Design_Compiler (standard cell ASIC, ARtisan TSMC library), and
from Synopsys FPGA-Express (Xilinx Student Edition 2.1i) agree with
the simulated results.

One word of caution, a right-shift (>>) on a verilog-integer (which
is signed) is performed UNsigned!  This is NOT what you would expect...

.......

module stupid_adder( i_a, i_b, o_sum);

  parameter I_W = 8;  // Input width (#bits), user-adjustable (1..32)

  // don't change these two params
  parameter O_W = I_W+1;  // output width (#bits), DO NOT MODIFY!
  parameter VINT_W = 32;  // CONSTANT, Verilog integer width, DO NOT
MODIFY!

input [(I_W-1):0] i_a;  // signed input A
input [(I_W-1):0] i_b;  // signed input B

output [(O_W-1):0] o_sum;  // signed output sum = i_a + i+b

integer int_a, int_b;  // intermediate integer variables
integer int_sum;       // intermediate sum

// sign-extend from (I_W) to 32-bit signed integer.
function [ (VINT_W-1):0 ] sign_extend;
  input [ (VINT_W-1):0 ] input_a;
  input [ 5:0 ] input_width;
  reg [5:0] i;
  begin
      // 1) copy lower-bits to output
      for ( i = 0; i < input_width; i = i + 1 )
        sign_extend[ i ] = input_a[ i ];

      // 2) replicate sign-bit to upper output bits
      for ( i = input_width; i < VINT_W; i = i + 1 )
        sign_extend[ i ] = input_a[ input_width - 1 ];
  end
endfunction  // function [ (VINT_W-1):0 ] sign_extend;

// here's some *real* work being done, sort of...

begin
  // sign-extend from (I_W) to 32-bit signed integer.
  int_a = sign_extend( i_a, I_W );
  int_b = sign_extend( i_b, I_W );

  int_sum = int_a + int_b;
end

assign o_sum = int_sum;  // auto-truncate the upper bits

endmodule

/////////////////////////////////////////////////

module test_the_stupid_adder;  // ahahahahahahahahahahahahahahahahahahah

  parameter I_W = 8;  // Input width (#bits), user-adjustable (1..32)

  // derived parameters, don't change these two params
  parameter O_W = I_W+1;  // output width (#bits), DO NOT MODIFY!
  parameter VINT_W = 32;  // CONSTANT, Verilog integer width, DO NOT
MODIFY!

  // derived parameters, don't change these two params
  parameter T_LOW = (-1) << (O_W-2);
  parameter T_HIGH = ((1) << (O_W-2)) - 1;

wire [(I_W-1):0] i_a;  // signed input A
wire [(I_W-1):0] i_b;  // signed input B

wire [(O_W-1):0] o_sum;  // signed output sum = i_a + i+b

integer int_a; // stimulus generator
integer int_b; // stimulus generator
integer int_sum; // device-under-test's output

integer loop_i, loop_j; // testbench variables

integer exp_sum; // expected output (calculated by testbench)

// sign-extend from (I_W) to 32-bit signed integer.
function [ (VINT_W-1):0 ] sign_extend;
  input [ (VINT_W-1):0 ] input_a;
  input [ 5:0 ] input_width;
  reg [5:0] i;
  begin
      // 1) copy lower-bits to output
      for ( i = 0; i < input_width; i = i + 1 )
        sign_extend[ i ] = input_a[ i ];

      // 2) replicate sign-bit to upper output bits
      for ( i = input_width; i < VINT_W; i = i + 1 )
        sign_extend[ i ] = input_a[ input_width - 1 ];
  end
endfunction  // function [ (VINT_W-1):0 ] sign_extend;

// drive inputs, convert integers into 8-bit bus
  assign i_a = int_a;
  assign i_b = int_b;

// capture the device output, convert to 32-bit signed integer

   begin
    int_sum = sign_extend( o_sum, O_W );
   end

// the device under test
  stupid_adder adder1( .i_a(i_a), .i_b(i_b), .o_sum(o_sum) );

initial
begin
  int_a = 0;  int_b = 0;
  $display("WILL TEST %d through %d", T_LOW, T_HIGH );

  for ( loop_i = T_LOW; loop_i <= T_HIGH; loop_i = loop_i + 1 )
    begin
      for ( loop_j = T_LOW; loop_j <= T_HIGH; loop_j = loop_j + 1 )
        begin
          int_a = loop_i;
          int_b = loop_j;
          exp_sum = int_a + int_b;  // calculate expected value
          #100;
          if ( int_sum != exp_sum )
            $display( "'%d' + '%d' = '%d', but got '%d'!", int_a,
               int_b, exp_sum, int_sum );
        end  // for ( loop_j = 0 ...
      $display("...working on %d of %d", loop_i, T_HIGH );
    end  // for ( loop_i = 0 ...
  #1000 $finish;
end

endmodule



Sat, 22 May 2004 14:02:37 GMT  
 Data Path synthesis Verilog(controlling bit-widths with signed quantities)

Quote:
> My question is: How do designers creating data-path intensive
> designs using Verilog, specially if the design has to support
> signed operands using 2's compliment arithematic.

Verilog registers and wires are unsigned only. This means that one has
to do manual sign-extension to get the necessary behaviour.

For example, when you add two 10 bit signed integers you expect 11 bit
signed result. So you have to sign-extend the operands before the
addition:

wire x[9:0];
wire y[9:0];
wire z[10:0] = { x[9], x[9:0] } + { y[9], y[9:0] };

Same goes for multiplications. If you multiply two 10 bits signed
numbers you expect 20 bits signed result. So you have to sign extend
the operands to 20 bits before the multiplication.

Of course, multiplication is better handled by a specialy designed
multipler rather than just writing 'x*y' in Verilog.

Overall - datapath coding is a pain in Verilog (things get really ugly
when you get to rounding, saturation logic, etc.)

--
Nimrod.



Sun, 23 May 2004 03:57:32 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Data Path synthesis Verilog(controlling bit-widths with signed quantities)

2. Making sense of [un]signed arithmetic and bit widths

3. SIMD-like bit-twiddling on odd-sized quantities

4. Making file path control only select directory paths not file names

5. ***Verilog,VHDL and Synthesis courses taught by author of Verilog book*******

6. ***Verilog,VHDL and Synthesis courses taught by author of Verilog book*******

7. ?list{proplist:width+proplist:group,SomeNr} does change field width, not group width

8. mixing 16-bit code and 32-bit data

9. Comparator between different bit widths

10. Q: Bit Widths of Subexpressions

11. 8-bit signed multiplier - RTL

12. 32-bit signed, unsigned and integers and overflows

 

 
Powered by phpBB® Forum Software