How to describe a signed multiplier using the Verilog 1995 standard - verilog

Using the 2001 standard signed multiplication is easy.
wire signed [7:0] A,B;
wire signed [15:0] Y;
assign Y = A*B;
I wonder how could this be done using the Verilog 1995 standard that has no 'signed' keyword.
Is there someone that remembers?
I do not have any idea on how to implement this in 1995 standard

You would have to explicitly sign extend A and B.
assign Y = {{8{A[7]}},A}*{{8{B[7]}},B};
I would not trust any tool that does not implement at least Verilog-2001.

According the the Sutherland text "Verilog-2001: " A Guide to the New Features of the Verilog Hardware Description Language"
"Verilog-1995 only provides one signed data type, the integer variable. The reg, time, and all net data types are unsigned. An integer variable has a fixed width of 32 bits (the IEEE standard defines integers as 'at lest 32 bits', but in virtually all simulators, integers are exactly 32 bits). With only one signed data type in Verilog-1995, most signed operations are limited to 32-bits wide."
Wire is a net data type.
A little farther down he goes on to say:
"The limitation is Verilog-1995 is that to model signed arithmetic, only 32-bit integers can be used."

Following Mikef answer I tried this.
https://www.edaplayground.com/x/EC5U
module mult1995(A,B,Y);
input wire [7:0] A,B;
output wire [15:0] Y;
integer Inta,Intb,IntY;
always#(A,B)
begin
Inta={{24{A[7]}},A};
Intb={{24{B[7]}},B};
IntY = Inta * Intb;
end
assign Y=IntY[15:0];
endmodule
In simulation it seems to work (did not run an extended simulation).
I synthesized this with Quartus and it does implement a signed multiplier.
It looks like this is was the way to go.
Still there where a lot of problems if you needed more than 32 bits.

Related

What is the goal of declaring an array with an offset? [8:1] instead of [7:0]

What is the goal of declaring an array with an offset? [8:1] instead of [7:0]
I'm used to declare my signals with reg [7:0] sig; for an 8b signal.
Declaring reg [8:1] sig; or even reg [1008:1000] sig; gives the same value with sig = 1; $display("sig=%d", sig);
What's the purpose of defining them like that? Is there any disadvantage on calculation(mismatch)? Especially when used with other signals starting from 0.
It depends on the logic you want to create that addresses each individual bit (you might want to read this article on Big-Endian versus Little-Endian. If you don't need to select individual bits, then the ordering and start bit is completely arbitrary.
If you are designing a positioning system, then it might even make sense to have negative indexes.

How do I invert a 64-bit variable in verilog?

I am trying to invert a 64-bit variable in verilog, but for some reason only one bit is inverted.
wire [63:0] bc;
assign bc = 64'b0;
assign notbc = ~bc;
I'm expecting the output to 64 bits of one's, but instead I get the most significant bit to be 1 and the others are 0's.
I also tried something else I found online:
assign notbc = bc ^ 64'b1;
but what I get this time is that the least significant bit is one and the others are 0's. What can I do to get the negation of every bit i.e. 64 bits of 1's?
Note: I'm limited to Verilog, I can't use SystemVerilog.
Here is the full module:
`timescale 1ns/1ns
module notting(
output [63:0] out);
wire [63:0] bc;
assign bc = 64'b0;
assign out = ~bc;
endmodule
It might just be missing from the code you pasted, but since notbc is not declared, it will be implicitly declared as a single-bit wire. With the following code you should be getting 64 ones, unless there is a problem with your simulator:
wire [63:0] bc, notbc;
assign bc = 64'b0;
assign notbc = ~bc;
I have checked your code in cloudv.io.
I have checked it works for small bitwidth
However, as I increased the bitwidth, the bug came out.
At this point I am not sure what causes the bug as I am not friendly with the system.
It seems like the bug can be reproduced when input is over fifty some bit wide.

Do outputs declared in output and reg both have to have number of bits?

Are these two lines of code in verilog the same?
output[1:0] r;
reg[1:0] r;
output[1:0] r;
reg r;
Do the number of bits have to be declared twice?
No. No No.
Verilog offers a few styles of declaring ports. The recommend way is known as ANSI-style, where you only mention the port name once.
module m(output reg [1:0] r, input clk);
It unfortunate that this style does not appear first in the LRM.
And, yes using the style in your question requires that the bit widths match.

What does the variable name in the register declaration indicate (Verilog)

I'm a just starting to learn verilog , and I'm having trouble with some things. I've found a few resources to help, but there are some things which aren't clear and I need specified. I have code for a D Flip-flop below. And I understand how the declaration for in and out work. What I dont get is the register.
When it says out is the variable associated with it.Does this association mean, out is the register along with output? Or does it mean out is also the output for the register?
module DFF(quarter, in, out) ;
parameter n = 1; // width
input quarter ;
input [n-1:0] in ;
output [n-1:0] out ;
reg [n-1:0] out ;
always #(quarter=1)
out = in ;
endmodule
In Verilog there are nets and there are variables. The most common kind of net by far is a wire, which you're probably familiar with. You can declare a variable using var, but most people say reg, because that is how it always has been done.
(In Verilog, but not in SystemVerilog), wires have to be driven by
assign statements
the outputs of instantiated modules
and variables have to be driven from
initial and always blocks.
Your output out is driven from an always block and so must be a variable. The line
reg [n-1:0] out ;
declares the output out as being a variable (rather than a wire).
In fact, you are using an old-fashioned way of specifying inputs and outputs. Since 2001, the way to do it is like this:
module DFF #(parameter n = 1)
(input wire quarter,
input wire [n-1:0] in,
output reg [n-1:0] out);
always #(quarter=1)
out = in ;
endmodule
This is the so-called ANSI form and, I think you would agree, is more sensible. I would advise using this form, not the old-fashioned form you are using.
BTW, you code is a bit strange. I'm not entirely sure what it's supposed to do, but this if you're expecting output to be driven by in when quarter is 1, I'd do it more like this:
module DFF // #(parameter n = 1) // you're not using parameter n
(input wire quarter,
input wire [n-1:0] in,
output reg [n-1:0] out);
always #(*)
if (quarter == 1'b1)
out = in ;
else
// IMPORTANT ! : what is out when quarter != 1 ?
// your current code would synthesise to a latch
// is that what you wanted? (And if so, are you
// sure that's what you wanted)
endmodule
initially verilog was though as a language which does behavioral types of operation on state variables (registers, reg) and connects them via nets. So, reg is a variable which is supposed to keep its value between operations, net is just a connection and has no state associated with it, i.e. wire. reg values can be calculated in procedural blocks, i.e. always block, wires can be connected only (using continuous assignments, assign statements (outside of the always blocks)).
There are different rules for using for regs and wires and different behavior of them in simulation, in particular around multiple drivers. See Matthew's reply for more info.

Verilog multiplication through repeated addition

I need help with a Verilog design I'm doing.
the idea is to do multiplication through repeated addition every time the M bit is set to 1/true. then I need to output that value. The assignment statement F=P; is throwing the error.
This is the error I'm getting
Error (10044): Verilog HDL error at Design2.v(13): expression cannot reference entire array "P"
It is my understanding that I can assign a register to an output if they are the same size. If I'm wrong then how can I implement this?
module Design2(A, N, M, F);
input A[7:0];
input N[3:0];
input M;
reg P[15:0];
output F[15:0];
always #(M) begin
repeat(N) begin
P = P + A;
end
F=P;
end
endmodule
Keeping apart the logic side, I can see two issues with your design.
As the comments pointed out, you have used unpacked arrays at wrong place.
Declaration of output port F.
For the first issue, the design needs a 16-bit vector for all the ports and variables. Here, the design takes a bunch of 8-bits as input A which must be declared as input [7:0] A, which is a packed array. Also, P needs to be a vector of size 16-bit in order to have contiguous operations.
This is to be done so that, when the statement P=P+A executes, the addition operation is done with all the variables taken with their respective sizes (size if P=16 and A=8). The overall addition is to be done with 16-bits, padding zeros in MSB side of A.
Hence, convert all the variables to packed array as follows:
input [7:0] A;
input [3:0] N;
input M;
reg [15:0] P;
output reg [15:0] F;
For the second issue, the design assigns output in a procedural always block.
wire elements must be continuously driven by something, and cannot store a value. Henceforth, they are assigned values using continuous assignment statements.
reg can be used to create registers in procedural blocks. Thus, it can store some value.
When an input port is connected, it has to be driven through continuous assignments from parent module, hence input ports are always wire. While output from a module can be driven continuously through a wire, or can be driven through procedural assignments through reg. Following image shows the port connection rules.
To accomplish this in current design, the output port must be declared as output reg [15:0] F. This is the cause of compilation error shown.
Either way, you can have output [15:0] F with no reg and make continuous assignment to F as follows. This will synthesize F to wire:
output [15:0] F;
assign F=P;
SystemVerilog adds a logic datatype to remove confusion between usage of wire and reg declaration. A logic can be driven by both continuous assignment or blocking/non blocking assignment.
// Either continuous assignment
output logic [15:0] F;
assign F=P;
// Or procedural assignment
output logic [15:0] F;
// Inside always block
F=P;
For more information on packed and unpacked array, refer SystemVerilog Arrays link. Regarding port declarations, refer Wire and Net pdf. Refer SystemVerilog IEEE 1800-2012 for more information on logic datatype.

Resources