signedness vs bit size - verilog

Given example below, with the simulators I've tried, the value of d2 is created by sign extending 4'sd2 - i1. From, my reading of the standard (1800-2012) I expect 4'sd2 - i1 to be treated as unsigned and zero extended in the same way as for d1.
What am I missing? Does the unsignedness of i1 somehow change as it is being widened from 2 to 4 bits? Thanks.
module sign_test(input clk, input /*unsigned*/ [1:0] i1,
output reg [7:0] d1, output reg [7:0] d2);
always #(posedge clk) begin
d1 = $unsigned(4'sd2 - i1); // this gets zero extended; the only possible values for 'd1' are 0, 1, 2 and 0x0f
d2 = 4'sd2 - i1; // this gets sign extended; the only possible values for 'd2' are 0, 1, 2 and 0xff
// but 11.8.1 says "4'sd2 - i1" should be unsigned:
// "-- For non-self-determined operands, the following rules apply:
// [...]
// -- If any operand is unsigned, the result is unsigned,
// regardless of the operator."
// and 'i1' is unsigned by default (adding "unsigned"
// explicitly doesn't change the behaviour).
end
endmodule

I think the reason for the difference is not to do with whether each expression is signed or unsigned, but instead to do with the number of bits Verilog uses to do the calculation.
This is a context-determined expression:
d2 = 4'sd2 - i1;
That means Verilog uses the maximum of all the widths involved (the widths of d2, 4'sd2 and i1, which is 8 (the width of d2). As you say unsigned arithmetic is done. With a value of 2'b11 for i1:
d2 = 00000010 - 00000011
which is
11111111
With
d1 = $unsigned(4'sd2 - i1);
however, the width of d1 is not taken into account, because of the call to the $unsigned system function. This makes the expression 4'sd2 - i1 a self-determined expression and so the bit width used for the calculation is 4 - the maximum of the widths of 4'sd2 and i1. So
0010 - 0011
is
1111
This is then zero-padded to
00001111
https://www.edaplayground.com/x/duY

Related

bit-wise negation in systemVerilog [duplicate]

This question already has an answer here:
What happened to this simple verilog ~^ operator?
(1 answer)
Closed 2 years ago.
In the code below, I was expecting "b" to be 2'b00 since "a" has fewer bits than "b" and they are unsigned wire. However, in the simulating result, "b" is 2'b10.
wire a;
wire [1:0]b;
assign a = 1'b1;
assign b = ~a;
I have tried to set "b" to width 3, and this time "b" is 3'b110.
wire a;
wire [2:0]b;
assign a = 1'b1;
assign b = ~a;
At my understanding, if RHS has fewer bits than LHS, the unused bits of the LHS should be 0s. Can anyone please explain why this is happening?
In the 1st case, a is 1 bit wide, but the LHS (b) is 2 bits wide. The assignment to b forces all values to be the maximum width (2). Before the bitwise negation, a is left-extended with 0's, becoming 2'b01. And, ~(2'b01) is 2'b10.
The same is true when b is 3 bits wide.
Refer to IEEE Std 1800-2017, section 11.6.2 Example of expression bit-length problem.

Verilog: Aligning valid and invalid bytes from a dynamic input

I'm trying to design a system that takes an 8 byte data input and an 8 bit valid input every clock cycle where each bit on the valid input either validates or invalidates a data byte.
input wire [63:0] d_in;
input wire [7:0] v_in;
The program should process d_in aligning all the valid bytes as follows.
(where B is a valid byte and X is an invalid byte)
Instance 1:
d_in = B1 B2 X X B3 X B4 B5
d_out = B1 B2 B3 B4 B5 X X X
Instance 2:
d_in = X B1 B2 B3 X B4 B5 B6
d_out = B1 B2 B3 B4 B5 B6 X X
I've mainly worked with algorithms before where all bit manipulation was the same every iteration e.g.assign d_out [7:0] = d_in [15:8]; but the fact that the quantity and order of valid bytes can change with every data input means this strategy cannot be used.
My question:
Is there a way to realise this function in using Verilog or VHDL? If so can someone point me towards a high level solution or some relevant reading so I can understand this concept better. I think if I understood at a high level then I'd be able to take a stab a coding it but currently I'm not even sure what I need to be coding.
Thanks
Zach
Since you asked for high level I will give a pseudocode example of something that might work, or at least get you going.
d_out = '0; //Assuming that the X bytes can be set to zero in the output.
bytes = 0;
for i in range(8)
if v_in[i]
d_out[bytes*8 +: 8] = d_in[i*8 +: 8] //Note the +: notation which is not pseudo, but verilog.
bytes++
Now perform this sequential code in an always block and you should be set.
Note: How the synthesized result from this will look is not entierly clear to me, but i suspect it will generate quite a bit of hardware.
I have something similar but not quite.
Input data into a FIFO, pre-calculate a byte-enable with the FIFO entries.
On the output side, read the the byte enable portions and use it to shift out bytes. So there are only eight conditions to satisfy for the byte enable...
1 byte, byteEn(0 downto 1) = "10", shift left 1 byte
2 bytes, byteEn(0 downto 2) = "110", shift left 2 bytes
3 bytes, byteEn(0 downto 3) = "1110", shift left 3 bytes
...and so on...
As you shift, read in the next word using the FIFOs read enable.
Note you will need to take care of when the FIFO is empty but not halt the pipeline so data already present continues to be shifted out.
Not sure how complicated it will be as I have glossed over it a bit.

What is >>>symbol in verilog?

May I know what is this symbol >>> in verilog. When should I use it? Thanks!
e.g
always #(posedge Clock) begin
if (Clear) begin
a < = c>>>8;
b < = d>>>16;
end
end
It is an arithmetic right shift operator (see page 19-20 of the link). It is the reverse case from Java (Java >> is arithmetic right shift, while >>> is logical right shift).
Arithmetic right shift is to handle case when the number right-shifted is positive/negative with this behavior:
Shift right specified number of bits, fill with value of sign bit if
expression is signed, othewise fill with zero
To illustrate, if you have signed expression with value of, say like this:
1000 1100
--------- >>> 2
1110 0011 //note the left most bits are 1
But for unsigned:
1000 1100
--------- >>> 2
0010 0011
The left most will be filled with 0.

What is "??" in Verilog casez?

I have a module below:
module bai1c(a, b0, b1, b2, b3, c);
input [2:0] a;
input [3:0] b0, b1, b2, b3;
output reg[3:0] c;
always #(a or b0 or b1 or b2 or b3) begin
casez(a)
3'b000: c = b0;
3'b001: c = b1;
3'b010: c = b2;
3'b011: c = b3;
3'b1??: c = 4'b0000;
endcase
end
endmodule
What kind of circuit will be synthesized?
When the condition 3'b1?? happen? (what ?? is?)
? is a don't care value - i.e. it will match either 0, 1 or z. So the 3'b1?? case will occur whenever the first bit is 1, no matter what the other two bits are.
The circuit is basically a 4:1 multiplexer, selecting one of b0,b1,b2,b3, with an added select bit on a that forces the output to 0, no matter what the other two select bits are.

Fixed combinatorial logic

I have question.
my code is
module pulsing(OUT, an1, an2, or1);
input wire an1, an2, or1;
output wire OUT;
wire afa;
and andik(afa,an1,an2);
or orik(OUT,afa,or1);
endmodule
I got after synthesis one 3bit LUT result, but I really need 2 different
LUTS .
How can I implement it without any sequential logic(just wires and
LUTs)?
Thanks!
You can define LUT2 as for AND gate:
LUT2 #(.INIT(4'h1)) U1(.O(O),
.I0(I1),
.I1(I2));
And OR gate respectively as:
LUT2 #(.INIT(4'hE)) U1(.O(O),
.I0(I1),
.I1(I2));
Notice the .INIT values. These are the truth table results of these Boolean functions.
I1 I0 O
0 0 B0
0 1 B1
1 0 B2
1 1 B3
From this you can implement any 2 input Boolean function with a single LUT2. For example XOR would require .INIT(4'h6).

Resources