typedef union {
logic [1:0] c3;
bit [3:0] a3;
byte b3;
} pack3;
pack3 p3;
According to LRM, the default initialization is according to the first member of union i.e logic in above example, therefore, c3 assign to X and rest to assign to 0 but when I compile in ModelSim and check in object window then there is a different result for a3 and b3.Also when I assign p3.a3 = 4'b0010; the value of a3 and b3 changes but not c3.Please Explain? I know there is only memory available for each variable so update in any value reflects all.
There are no guarantees if you write to one member of an unpacked union and try to read another member (except for one special provision mentioned at the end of section 7.3 Unions in the 1800-2012 LRM). You need to use a packed union if you want a guarantee in the layout of overlapping members.
Related
I'm trying to decipher the following line of code in Verilog:
assign ASIC_error_flag = (StartTransfer & ~Bank_Slct[IO_Config_P2[13:12]]);
I suspect it might be a compare between the negated bus "Bank_Slct" and bits 13 through 12 of the bus IO_Config_P2, but I've never seen a bus inside of a bus like that before. What is this supposed to equate to?
The inner square brackets are used to select a portion of the IO_Config_P2 signal, and the outer brackets are in turn used to select a portion of the Bank_Slct signal.
Let's assume you declared Bank_Slct like a memory of 4 bytes:
reg [7:0] Bank_Slct [0:3];
In this case, you need a 2-bit signal to select one of the 4 bytes (like a memory address). The expression, IO_Config_P2[13:12], is the 2-bit select signal.
When IO_Config_P2[13:12] is equal to 2'b00, you are selecting byte Bank_Slct[0].
When IO_Config_P2[13:12] is equal to 2'b01, you are selecting byte Bank_Slct[1], etc.
An alternate approach would have been to create a separate signal (sel), then use that:
wire [1:0] sel = IO_Config_P2[13:12];
assign ASIC_error_flag = (StartTransfer & ~Bank_Slct[sel]);
Refer to IEEE Std 1800-2017, section 7.4.4 Memories.
I am somewhat new to verilog and I have a question that is confusing me .
I have a number of constant parameters , specifically nearly 1023 of them c0 , c1,c2 ..... c1022, each one being 10 bit in length . I also have a vector r[1022:0] , which is 1023 bits in length . My task is to compute ci*r[i] where i varies from 0 to 1022 and finally take the xor of the 1023 10 bit vectors that i get.When I do this in simulation , verilog generates the output at time 0 for the assign statement . How can verilog generate the output at time 0 ? Will there be no delay associated with these 1023 xors?
Also, if I need to do this succinctly , is there a short form that I can use or do I need to manually write c0 *r[0] ^ c1 *r[1] ......^ c[1022]*r[1022] which is synthesizable ?
A Verilog simulator will execute whatever legal syntax you give it—the tool knows nothing about what the implementation eventually looks like. It's up to you to feed timing constraints to the synthesis tool and it tells you if it can fit the logic to meet the constraints (or you might have to run another tool to see if it meets timing constraints).
Since you named your parameters c0, c1, c2, ..., you might as well named them czero, cone, ctwo, ... which gives you no options for shortcuts.
If you tool supports SystemVerilog, you can write your parameter as an array and then use the array xor reduction operator
parameter [9:0] C[1023] = {10'h123, 10'h234, ...};
assign out = C.xor() with (item*r[item.index]);
If you synthesis tool does not support this SystemVerilog syntax you, you can pack the parameter values into a single vector and use an indexed part select in Verilog.
parameter [10220-1:0] C = {10'h123, 10'h234, ...};
function [9:0] xor_reduction (input [1022:0] r);
integer I;
begin
xor_reduction = 0;
for(I=0;I<1023;I=I+1)
xor_reduction = xor_refuction ^ (r[1022-I]*C[I-:10]);
end
endfunction
assign out = xor_reduction(r);
I am a beginner in Verilog.I need to understand the logic of a testcase but I am having difficulty because of the logic of these variables.
Are these 'define F and G of integer types.I read that parameter are constants.
'define F 32
'define G 0
module M(...);
parameter pMaxPacketsSize =1024;
localparam pTotalBits=3*'G;
localparam pForcePktSize=(pMaxPacketsSize-'F);
localparam pLastPacketSize =((pTotalBits-1)%(pForcePktSize))+1;
localparam pNumTransactions=((pTotalBits-1)/(pForcePktSize))+1;
localparam pPortSize=(pNumTransactions>1)?pMaxPacketsSize:((((pTotalBits-1)/32)+1)*32)+'F;
As G is defined to be 0,
what will be the value of ForcePacketsize.I attempted binary subtraction and arrived at 128(7 bits)[Is this Correct?].[0-32].Are all these operations needs to be performed in binary arithmetic.I want to know the value of these parameters(pForcePktSize,pLastPacketSize,PNumTransactions).
One more statement I want to understand is this:
wire[pPortSize-1:0]D;
wire[pNumTransactions-1:0] t;
assign t=1'b1<<D[14:0];
I know it is of type :[size][radix][value] means 1 in binary then left shifting,but how this is being assigned to array(will t be 100000000000000 14 zeroes and then 1)
I tried to run online on some IDE's but get error that I give up.
`define in verilog is the same thing as #define in c. It defines a text macro. `G and `F instantiate macros and get replaced by their context in the program before parsing.
So, in your case
localparam pTotalBits=3*'G;
localparam pForcePktSize=(pMaxPacketsSize-'F);
will be replaced with
localparam pTotalBits=3*0;
localparam pForcePktSize=(pMaxPacketsSize-32);
The replacement is textual and instantiations of the macros just got replaced with their definitions. There is no type associated with macro definition.
Consider the following module:
module power(input [11-1:0] xi,xq,output [22-1:0] y);
assign y = xi*xi + xq*xq;
endmodule
I know that my single assignment is actually decomposed of 3 steps: 2 squares and one addition. My question is how would the synthesizer decides on the bitwidth of the intermediate steps xi*xi and xq*xq?
I noticed that when running logic equivelance circuit (lec) for the above code, it causes trouble and could only be solved by decomposing the single assignment into three assignments as follows:
module power(input [11-1:0] xi,xq,output [22-1:0] yy);
wire [21-1:0] pi,pq;
assign pi = xi*xi;
assign pq = xq*xq;
assign yy = pi+pq;
endmodule
Here's how your simulator decides on bitwdith for intermediate results.
Verilog Simulation
This expression - assign y = xi*xi + xq*xq; - is an example of a context determined expression. A Verilog simulator takes the widest of all the nets or variables in the expression and uses that. So, in your code, the widest is y at 22 bits wide, so Verilog will use 22 bits throughout.
VHDL Simulation
The behaviour of a VHDL simulator depends on the package used. If you use the numeric_std package, as is recommended, then you would need to obey the following rules:
The width of the sum should be the same as the wider of the two operands.
The width of the product should be the sum of the widths of the operands.
Therefore, your code would compile if translated directly into VHDL:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity power is
port (xi, xq : in signed(11-1 downto 0);
y : out signed(22-1 downto 0));
end entity power;
architecture A of power is
begin
y <= xi*xi + xq*xq;
end architecture A;
Shouldn't everything be signed?
Given the names of your module (power) and inputs (xi and xq) and having spent 25 years designing radio systems, shouldn't they be signed? Shouldn't your Verilog be:
module power(input signed [11-1:0] xi,xq,output signed [22-1:0] y);
assign y = xi*xi + xq*xq;
endmodule
That is why I chose the signed type from numeric_std, not the unsigned type.
Synthesis
Well, I've waffled on about simulators, but you asked about synthesis. And, to be frank, I don't know what a synthesiser would do. But, given the job of a synthesiser is to design a logic circuit that behaves exactly like the simulation, you would think that any self-respecting synthesiser would use the same bit-widths as the simulator. So, I'm pretty sure that's your answer.
Can you use a parameter value for assignment in verilog? Can I somehow define the width of a parameter variable?
Ex:
module mymodule #(parameter type =2)
(...
output [(3+type)-1:0] out);
wire [2:0] rate;
...
assign out = {rate, {1'b0{type}} };
endmodule
Lets just say type=2. Then I would want out to be of bit-length 5. rate is still of bit-length 3 (lets just say it is 3'b100), when I assign out I want it to be 100 000.
Similarly if type=6. Then I would want out to be of bit-length 9. rate is still of bit-length 3 (again lets say its 3'b100), when I assign out I want it to be 100 000000.
I don't get any syntax errors but when I try to simulate it I get:
"error: Concatenation operand "type" has indefinite width"
How would you guys approach a design problem like this one?
You have the repetition operator backward. Should be
{type{1'b0}}, not {1'b0{type}}
I'm surprised you don't see any syntax error from that.