Our professor gave us this skeleton for a case statement, and so far no one is able to understand what it's doing.
always#(*)
begin
case(state)
3'b000:{nout, nstate} = (in)?(in=1):(in=0)
endcase
end
More insight:
This is being implemented as a button debouncer.
nout is the output of the next state: a single bit
nstate is the next state: 3 bits
in is also 1 bit wide
My understanding is that the concatenation operator will append nout to nstate resulting in 4 bits. (ie: if nout is 1 and nstate is 010, this part of the statement will produce 1010)
On the other side of the equality assignment we have a simple comparator, which upon further inspection, doesn't seem to do anything...
It's basically saying
if(in == 1) {
in = 1;
} else {
in = 0;
}
With that understanding, we're assigning a single bit to nout and nstate?
This understanding doesn't make any sense to me. I've compared my notes with 2 other classmates whom wrote the exact same thing so I'm thinking either we don't understand the code or there's an error.
Further insight:
Upon researching further, I've found the state diagram appear in multiple places, which makes me fairly confident that this is a common Moore Machine.
i hope that you did not cut and paste those expressions correctly.
3'b000:{nout, nstate} = (in)?(in=1):(in=0);
The above statement is a complete mess. Most likely it will fail any linting. It might be ok syntactically, but makes no sense logically and makes such code unreadable and not maintainable. It has to look like the following:
3'b000:{nout, nstate} = (in)?(1'b1):(1'b0);
The left hand side concat represents a signal with lower 3 bit associated with nstate, and upper n bits with nout. The right hand side ternary operator produces either one bit '1' or 1 bit '0' (actually id does the same int the original expression, because 'in' is 1 bit wide. Verilog will extend the rhs one bit to the size of the lhs and add missing '0's. As a result nout will be 0 and nstate will be either 3'b000 or 3'b001, depending on the value of in.
Related
I have an inferred latch problem after synthesis when I designed a simple dual port RAM block. Due to large code size, I have just embedded this always block code as follows:
integer i;
always_latch
begin
for (i=0;i<NUM_RAMS;i=i+1) begin
if (ena_t == 1) begin
w_addra_t[i] = w_addra[i];
end
else begin
w_addra_t[bank_addra[i]] = w_addra[i];
end
end
end
My RAM block includes NUM_RAMS numbers of banks. The addresses of respective input data are stored in w_addra.
Data with given w_addra addresses are scrambled into w_addra_t depend on the values of respective bank_addra (depend on access pattern) when ena_t = 0.
I tried to replace for loop with if...else, switch...case, generate but the problem is same. With different always block in my code that the left-side is with only w_addra_t[i] in both if.else of ena_t, there is no error.
I would like to get your suggestion if you have any idea. I did look for similar issue but getting no results.
Thanks very much :)
My guess is the entries for bank_addra are not guaranteed to be unique. If two or more entries hold the same values then an index hole is created for w_addra_t; which will infer a latch.
Here are three possible solution:
Functionally guaranteed that bank_addra entries will have unique values, then the synthesizer should not infer a latch. This can be challenging.
Move the address variation from the LHS to the RHS so that each index of w_addra_t is guaranteed to be assigned a value. Ex change w_addra_t[bank_addra[i]] = w_addra[i]; to w_addra_t[i] = w_addra[bank_addra_lookup[i]];.
Assign all entries of w_addra_t to a known value (constant, flip-flop, or deterministic value) before other logic. You can put this default assignment at the top of your always block (option 1 example) or above the logic where the latches were about to be inferred (option 2 example). This is the simplest solution to implement assuming it still satisfies relational requirements with your other code.
// NOTE: SystemVerilog supports full array assignments (Verilog requires a for-loop)
always_comb
begin
w_addra_t = '{default:'0}; // <-- default assignment : option 1
if (ena_t == 1) begin
w_addra_t = w_addra;
end
else begin
w_addra_t = w_addra_t_ff; // <-- default assignment : option 2
for (i=0;i<NUM_RAMS;i=i+1) begin
w_addra_t[bank_addra[i]] = w_addra[i];
end
end
end
always_ff #(posedge clk) begin
w_addra_t_ff <= w_addra_t; // assuming w_addra_t should hold it current values
end
TL;DR
always_latch is a SystemVerilog keyword to identify explicit latches. Some tools will auto-waive the warning when the keyword is used, but will throw an error/warning if the keyword is used and a latch is not detected.
If you know it should be combinational logic, then use the always_comb SystemVerilog keyword. With always_comb, if the synthesis detects a latch then it should report an error.
Read related question:
What is inferred latch and how it is created when it is missing else statement in if condition. Can anybody explain briefly?
I don't know if it will solve your problem by changing to
int i
always_comb
instead. Perhaps the tool gets sad when you use a 4-state variable like integer?
Computer Organization and Design (5th edition) by Hennessy and Patterson includes this Verilog code in Figure B.5.15 (p. B-37):
ALUOut <= A < B ? 1:0;
Is there any reason not to write this simpler statement instead:
ALUOut <= A < B;
In general, is there ever a reason to write "? 1 : 0" in Verilog?
The only people that can answer why they chose one way or the other are the authors. Many of the same people prefer to write if (expr != 0) instead if (expr). Maybe they come from VHDL and want to be more explicit.
The only reason I can think of why writing expression ? 1: 0 might be needed is when the expression evaluates to 'z and you want to convert it to 'x.
I've seen Verilog code where the bitwise or operator ("|") is used monadic. What's the purpose?
For example
| address[15:14]==0
or
|address[15:14]? io_din : ramrd
Cann't we omit the "|" in these cases?
In this case it acts as a reduction operator, for example:
|4'b1000 => 1'b1 (OR)
&4'b1000 => 1'b0 (AND)
^4'b1000 => 1'b1 (XOR)
|4'b0000 => 1'b0
&4'b1111 => 1'b1
^4'b1111 => 1'b0
ORing the entire bus to a 1 bit value, or applying an AND/XOR to the entire bus.
This is referred to as a 'unary' operator as it only take a right hand argument. They are covered in Section 11.4.9 of SystemVerilog IEEE1800-2012.
|address[15:14]? io_din : ramrd
is the shortcut for writing
(address[15] | address[14]) ? io_din : ramrd
i.e bitwise ORing of all bits of the bus together to generate a 1bit value.
In this case it will evaluate as HIGH if either(or both) bit 15 OR bit 14 is HIGH.
similarly you can write other bitwise operators
&address[15:14]? io_din : ramrd // ANDing
^address[15:14]? io_din : ramrd // XORing
In the examples provided, the code with | is functionally equivalent to the same coded with the | omitted. Three possible reason to have and keep the | for the provided code are:
It gives guidance to the synthesizer: first OR the address bits then compare to 0, instead of comparing each address bit to 0 then ANDing the results. It is the same functional result with different gate configurations.
It following a coding style or formatting style requirement.
It just read better (visually/structurally appealing) because there is a |address[15:14]==1 on a near by line of code to |address[15:14]==0. (Reminder: |address[15:14]==1 is not the same as address[15:14]==1)
On the specific question of whether the '|' can be omitted in these cases:
Whether |address[15:14] and address[15:14] are identical depends on the context (in general, they aren't, because unknowns are handled differently). Your first example compared to 0, and it's true that the | can be dropped in this particular case, but it wouldn't be true if you compared to anything other than 0.
Your second example is trickier. The LRM doesn't appear to specify how the first expression in a ternary is evaluated. I know of 2 sims that evaluate it as a reduction-OR, so the | can be dropped in those cases. However, if a sim instead evaluates it in the same way as an if (ie if(address[15:14])) then the | is required.
Synthesis is simpler, of course, since the synthesiser doesn't have to worry about unknowns.
Say I have a scenario in which I need to compare only a few bits of a register and I don't care about other bits. eq, I need to check the first and last bits of a 3 bit register (A[2:0]) and I don't care about the middle bit, say compare vector is 3'b1X0 (Parameter).
Simplest way to do this is choose all the bits I care about, AND them and I have generated a control signal:
if ((A[2]==1) & ((A[0]==0)) Here the condition inside if statement is my control signal.
Another way is to use a casex statement: casex(A) begin 3'b1?0: ... , ... endcase.
Is there anything like ifx-elsex statement or something that can be used to do this kind of operation without using the 1st and 2nd method?
Thanks!
if (A[2:0] inside {3'b1?0} )
SystemVerilog keyword inside. It has been supported since at least Accellera's SystemVerilog 3.1 (before SystemVerilog was a part of IEEE). IEEE Std 1800-2012 11.4.13 has examples of use. inside is synthesizable.
There is also if ( A[2:0] ==? 3'b1?0 ) (IEEE Std 1800-2012 11.4.6). The only reference I have on hand (a book published 2004) says it is not supported for synthesis yet. You are welcome to try it.
(A[2]==1) is a logical expression the & is a bitwise operator, although either works it would be better semantics to use the && logical and operator. This is slightly different to most other languages where the && is a short-circuit operator.
Logically what you want is if ((A[2]==1) && ((A[0]==0)) but it could be reduced to a bitwise expression :
if ( ~A[0] & A[2] )
NB: Try to avoid using casex, the unknown parts will match x's in simulation. Try to use casez instead, ? can still be used to match don't cares.
Update comparing inside to casez
Case statements a clean control structure used in most languages to avoid large if elsif else chains. the inside operation will match x's to the do not care '?' values. this makes it usage similar to the casex which is considered to be bad practise to use as it can hide simulation fails.
casez(sel)
4'b1??? a= 3'd4;
4'b01?? a= 3'd3;
4'b001? a= 3'd2;
4'b0001 a= 3'd1;
4'b0000 a= 3'd0;
endcase
vs
if (sel inside {4'b1???})
a= 3'd4;
else if (sel inside {4'b01??})
a= 3'd3;
else if (sel inside {4'b001?})
a= 3'd2;
...
The above is actually equal to the casex (but more verbose) I believe that instead of casex you could also use :
case(sel) inside
4'b1??? a= 3'd4;
4'b01?? a= 3'd3;
4'b001? a= 3'd2;
4'b0001 a= 3'd1;
4'b0000 a= 3'd0;
endcase
but then I would never use a casex.
There's no operator I'm aware of that allows you to use '?' or 'x' inside an equality comparison to have them ignored.
Another alternative that you didn't mention would be to use a bitmask to select the bits you only care about. If you have a lot of bits this can be more compact than testing each bit individually.
If you only care about A == 3'b1?0, then it can be written as such:
if((A & 3'b101) == 3'b100)
I have an input port from_LS(511:0). This is declared as wire in my module. I am assigning this to a set of 32 registers ilb(0:31), each of which are 1 nits long. I was trying to use the for loop to do this.
integer i;
genvar j;
initial
begin
count1 = 0;
count2=0;
flush_ctrl=0;
buffer_bit=0;
a=(hmic_ctrl[1]) + (hmic_ctrl[2]*2) + (hmic_ctrl[3]*4);
//assigning data from LS to ilb
for (i=0;i<=31;i=i+1)
ilb[i]=from_LS[511-(16*i) : 511-(16*(i-1))];
ilb[0]= from_LS[511:496];
ilb[1]= from_LS[495:480];
ilb[2]= from_LS[479:464];
ilb[3]= from_LS[463:448];
ilb[4]= from_LS[447:432];
ilb[5]= from_LS[431:416];
ilb[6]= from_LS[415:400];
ilb[7]= from_LS[399:384];
ilb[8]= from_LS[383:368];
ilb[9]= from_LS[367:352];
ilb[10]= from_LS[351:336];
ilb[11]= from_LS[335:320];
ilb[12]= from_LS[319:304];
ilb[13]= from_LS[303:288];
ilb[14]= from_LS[287:272];
ilb[15]= from_LS[271:256];
ilb[16]= from_LS[255:240];
ilb[17]= from_LS[239:224];
ilb[18]= from_LS[223:208];
ilb[19]= from_LS[207:192];
ilb[20]= from_LS[191:176];
ilb[21]= from_LS[175:160];
ilb[22]= from_LS[159:144];
ilb[23]= from_LS[143:128];
ilb[24]= from_LS[127:112];
ilb[25]= from_LS[111:96];
ilb[26]= from_LS[95:80];
ilb[27]= from_LS[79:64];
ilb[28]= from_LS[63:48];
ilb[29]= from_LS[47:32];
ilb[30]= from_LS[31:16];
ilb[31]= from_LS[15:0];
pctr(
.clk(clk),
.reset(0),
.offset(branch_ctrl[13:1]),
.mux_select(branch_ctrl[0]),
.pc1(pc)
);
end
I was getting the error that I should not use a variable index. The error is :
# ** Error: C:/Modeltech_pe_edu_10.0/examples/COMP ARC/inst_line_buf.v(55): Range must be bounded by constant expressions.
So i wrote down the following:
ilb[0]= from_LS[511:496];
ilb[1]= from_LS[495:480];
ilb[2]= from_LS[479:464];
....
ilb[31]= from_LS[15:0];
But i guess there must be a better way to do this. Could anyone tell me how?
The orginal verilog doesnt allow this kind of expression as it wanted to assure that the width is always right (it is, but in earlier times compilers werent as good :-).
Verilog 2001 offers some solution with +: you can specify the width
e.g. from_LS[ 511-(16*i) +:16 ] in your loop.
EDIT: Another solution would be to put another loop inside, which copies 16 bits bit by bit.
You should include more code (at least up to the always block containing that loop for the sensitivity list) and the exact error you're getting.
Does it work if you change integer i to genvar i and wrap the for in generate and endgenerate?