Verilog while error - verilog

I have a school project in Verilog and I am very newbie at it. A part of the program is this
integer x;
assign x=1;
**LINE 49** while(x<=9)
begin
assign lastBitsofP=P[1:0];
if(lastBitsofP == 2'b00 || lastBitsofP ==2'b11)
begin
rightShift r1(shiftedValue,P);
end
x=x+1;
end
but I always get this error : "mainModule.v" line 49 expecting 'endmodule', found 'while' ,

You need to stop coding and think about what is going on. You are modelling hardware and connections. When you write assign x = that means "I have a wire and I want you to drive that wire with this value". If you have a module like r1 that you want connected it must be connected always you can't go "oh wait, if this happens just create a multiply unit for me".
You need to instantiate your connections at the start. If you only want the right shifted value sometimes then you can have a statement like assign out = select ? shiftedValue : unshiftedValue; And then you just need to write the logic for select.
And you'll probably want a flip-flop for your output. Something like
reg [31:0] result;
always #(posedge clk)
begin
result <= out;
end

Related

Bit by bit comparison between two variables in Verilog

Currently, I am beginning to write the firmware by Verilog for one idea. It is comparing bit by bit between two variables and then using one binary counter to count the number of different bits.
For example:
I have two variables in verilog
A : 8'b00100001;
B : 8'b01000000;
Then I give the condition to compare bit by bit between two variables. If there is difference between 1 bit of A and 1 bit of B at same bit position, binary counter will count.
This is my verilog code:
module BERT_test(
input CLK,
input RST,
input [7:0] SIG_IN,
input [7:0] SIG_OUT,
output [7:0] NUM_ERR
);
integer i;
reg[7:0] sign_in;
reg[7:0] sign_out;
always #(posedge CLK) begin
sign_in[7:0] <= SIG_IN[7:0];
sign_out[7:0] <= SIG_OUT[7:0];
end
reg [15:0] bit_err;
// Combinational Logic
always #* begin
bit_err = 8'b0;
for (i=0;i<8;i=i+1) begin
if (sign_in[i] == sign_out[i]) begin
bit_err = bit_err + 8'b0;
end else begin
bit_err = bit_err + 8'b1;
end
end
assign NUM_ERR = bit_err;
end
endmodule
Then I had a mistake
Reference to vector wire 'NUM_ERR' is not a legal reg or variable lvalue
I do not know how to solve this problem. Are there any solutions for this problem or how I need to modify my firmware, please suggest me.
You are driving NUM_ERR (a net) from an always block. It is not permitted to drive nets from always blocks (or initial blocks). You need to move this line:
assign NUM_ERR = bit_err;
outside the always block.
You should not use an assign statement inside an always block. This is legal but is deprecated and means something weird. If you have included this line inside the always block by mistake, then indenting you code properly would have shown it up.
You have an assign WITHIN an always block. Move it outside.
Adding zero to bit error if the bits are the same is superfluous.
if (sign_in[i] != sign_out[i])
bit_err = bit_err + 8'b1;
Also bit error is 16 bits so it is not wrong to add 8'b1 but misleading.

I get this error vlog-13069

First of all, sorry for my English skills.
I am studying Verilog and I have this code
module paralelo_serie ( data_in,clk, D_serie, nSyn, Done );
input wire [12:0] data_in;
input clk;
output reg D_serie, nSyn, Done;
genvar i;
84 if (data_in == 0) Done= 1;
else....
When I try to compile this code, I get this error message:
Error: (vlog-13069) C:/Users/Pedro/Documents/master/asignaturas/primer cuatrimestre/Metodologia de diseño y herramientas cad/proyecto digital/proyecto digital.v(84): near "=": syntax error, unexpected '='.
Error: C:/Users/Pedro/Documents/master/asignaturas/primer cuatrimestre/Metodologia de diseño y herramientas cad/proyecto digital/proyecto digital.v(84): (vlog-13205) Syntax error found in the scope following 'Done'. Is there a missing '::'?
I am a beginner at this language and I don't know what happened. I get this error a few times in the code, but I can solve it sometimes by changing the reg to wire and other time change blocking assignment to no blocking... I don't really know how I can fix and really I am getting frustrated... please help, you are my last hope...
Sorry I forgotten, I use modelsim 10.4 student version
AS toolic has mentioned the 84 looks like it was just an accidental cut and paste from your code.
If statements, unless they are for the generate statement need to be contained with in a process ( some call it a block ). This can be an initial or an always.
For combinatorial logic :
always #* begin
if (data_in == 0) begin
Done = 'b1;
end
else begin
Done = 'b0;
//...
end
end
Not defining Done in the else branch will result in a latch being created.
While learning I would recommend using begin end statements and indenting code well as this helps clarify the structure of code and makes typos a bit easier to spot.
If Done was left as a wire you could just have used:
assign Done = (data_in == 0) ;
On the other hand if you wanted Done to be driven synchronously :
always #(posedge clk) begin
if (data_in == 0) begin
Done <= 'b1;
end
else begin
//...
end
end
Note the change to non-blocking (<=) assignments to correctly simulate a flip-flops behaviour. As Done is a full flip flop (stateful) then there is no need for the synthesis tool to add a latch if it is not specified in the else branch, it will just retain its value.

7 Segment Display multiple conditions verilog

I know the question sounds strange and vague, but I got a problem getting around the Verilog.
I got a FSM which has to use a 4 7 segment displays, at one state it should show only one number on one display, at other it should use all 4 displays to display a string.
My question is how can I actually get around the always# blocks with this kind of problem.
I've tried setting in one always# two different cases in a If else block, but it didn't work out. Tried also making two modules one for the number and the other for the string, assigning different output ports but the thing is that it has to point to the same hardware ports, and it fails on the bitstream.
Could someone of you give me some tips?
Ok, I will post some code, but the main picture is that I have a master state machine and then I got another state machine. Depending on the state of the other FSM I output state number on the display. But in a different state of the master state machine I have to display a message on the 4 7segment displays. What I got now is:
Here I used CLK in order to make the message
always#(BIN_IN or CLK) begin
if(FAIL==1) begin
case(state)
left:
begin
HEX_OUT [6:0] <= F;
SEG_SELECT_OUT <= 4'b0111;
state <= midleft;
end
midleft:
begin
HEX_OUT [6:0] <= A;
SEG_SELECT_OUT <= 4'b1011;
state <= midright;
end
//same for the rest
end
else begin
case (BIN_IN)
4'h0 : begin
HEX_OUT [6:0] <= 7'b1000000;
SEG_SELECT_OUT <= 4'b0111;
end
//same logic for the other cases
Board used is Xilinx Basys 3 using vivado synthesising tool
Thanks
As Greg said:
always#(BIN_IN or CLK)
Infers combinational logic. An FSM cannot be created with combinational logic alone. As you know, a FSM needs to be able to store the state between each clock.
always#(posedge CLK)
Infers flipflops into your design. That is, the operations you do inside this always loop will be stored until the next positive edge. If you put all of the design inside this always block you will end up with a typical moore-machine where your outputs will only update on every positive clock edge.
It is a bit hard to understand what you are trying to create from your code-snippet. You are talking about two FSM's, but it seems to me that you are trying to do one combinational operation and one clocked operation. If you want your design to update some outputs - like BIN_IN - combinationally(that is, immediately) you have to do these assignments outside of the always#(posedge CLK) block. Use a always#(posedge CLK) block to update your FSM-values and then use a combinational always#(BIN_IN or FAIL) block to infer a multiplexer that will choose between your FSM-output and other outputs. Something like this might work:
always#(posedge CLK)
begin
case(state)
left:
begin
FAIL_HEX_OUT <= "A";
FAIL_SEG_OUT <= 4'b1011;
state <= midleft;
end
//Rest of statements
endcase
end
always#(FAIL or BIN_IN or FAIL_SEG_OUT or FAIL_HEX_OUT)
begin
if(FAIL == 1) begin
HEX_OUT <= FAIL_HEX_OUT;
SEG_SELECT_OUT <= FAIL_SEG_OUT;
end else begin
case(BIN_IN)
//your statements
endcase
end
end
Additionally, this wont work:
HEX_OUT [6:0] = A;
do this to assign ascii to a reg
HEX_OUT [6:0] = "A";
I also assume that you are using endcase to close your case-statements.
I have made your code-snippet compile here:
http://www.edaplayground.com/x/P_v
Edit:
I changed the sensitivity list on the combinational logic. The above code wouldn't have worked earlier.
Because you have posted so little of your code it is hard to figure out what you actual problem is. I assume that you only have one output port for to control all the 7-segment displays. In that case you need to cycle through each SEG_SELECT_OUT and set HEX_OUT for each display when you wish to output FAIL. This, in turn, implies that each display also has the ability to store the HEX_OUT signal that it receives, and your outputs (probably SEG_SELECT_OUT) must enable the write functionality of these display registers. Check that this is the case. I also assume that your real-time-counter that counts 30 seconds sets the FAIL flag when it completes, and is reset every time the maze(I have no idea what you mean when you say maze) is completed. You say that you need to change the number, and I assume that you are talking about outputting the number in BIN_IN on your display and that BIN_IN is changed elsewhere. All of this should work in the code above.
Without more information it is hard to help any further.

Getting strange error in verilog (vcs) when trying to use if/else blocks

I am trying to write an "inverter" function for a 2's compliment adder. My instructor wants me to use if/else statements in order to implement it. The module is supposed to take an 8 bit number and flip the bits (so zero to ones/ones to zeros). I wrote this module:
module inverter(b, bnot);
input [7:0] b;
output [7:0]bnot;
if (b[0] == 0) begin
assign bnot[0] = 1;
end else begin
assign bnot[0] = 0;
end
//repeat for bits 1-7
When I try and compile and compile it using this command I got the following errors:
vcs +v2k inverter.v
Error-[V2005S] Verilog 2005 IEEE 1364-2005 syntax used.
inverter.v, 16
Please compile with -sverilog or -v2005 to support this construct: generate
blocks without generate/endgenerate keywords.
So I added the -v2005 argument and then I get this error:
vcs +v2k -v2005 inverter.v
Elaboration time unknown or bad value encountered for generate if-statement
condition expression.
Please make sure it is elaboration time constant.
Someone mind explaining to me what I am doing wrong? Very new to all of this, and very confused :). Thanks!
assign statements like this declare combinatorial hardware which drive the assigned wire. Since you have put if/else around it it looks like you are generating hardware on the fly as required, which you can not do. Generate statements are away of paramertising code with variable instance based on constant parameters which is why in this situation you get that quite confusing error.
Two solutions:
Use a ternary operator to select the value.
assign bnot[0] = b[0] ? 1'b0 : 1'b1;
Which is the same as assign bnot[0] = ~b[0].
Or use a combinatorial always block, output must be declared as reg.
module inverter(
input [7:0] b,
output reg [7:0] bnot
);
always #* begin
if (b[0] == 0) begin
bnot[0] = 1;
end else begin
bnot[0] = 0;
end
end
Note in the above example the output is declared as reg not wire, we wrap code with an always #* and we do not use assign keyword.
Verliog reg vs wire is a simulator optimisation and you just need to use the correct one, further answers which elaborate on this are Verilog Input Output types, SystemVerilog datatypes.

Using if-else and foor loop inside an always block

I want to use if-else and for loop inside an always block. I don't want those if-else to be executed again and again, so I don't want to connect always with either posedge clkor negedge clk.
I want them to be executed only once. I not only want to simulate but I want to synthesize on to Spartan Board aswell.
always # (**what I should add here**)
begin
if(condition)
else
end
For simulations to execute some thing once you can use initial but this is not a synthesizable:
reg x;
initial begin
if(condition) begin
x = 1'b0 ;
end
else begin
x = 1'b1 ;
end
end
To answer the general question always #(**what I should add here**) Most modern verilog simulators will allow the use of * which will trigger the block (always begin to end) when any right hand side argument changes of any condition of selection logic.
always #* begin
if(condition)
x = y ;
else
x = ~y ;
end
older simulators would require you to list the variables you needed to trigger on, in a list. always #(condition, y)
If there is only 1 variable being selected an assign on a wire type might be better, but this can not be limited to being 'executed once', but would be a suitable choice from your question. Not sure about suitability for FPGA's though
wire [3:0] x ; //4 bit wire
//(condition) ? value if true : value if false ;
assign x = (condition) ? 4'b1010 : 4'b0100 ;
module oneShot(in, out, enable, reset);
input in;
input enable;
input reset;
output reg out;
reg once_only;
always # (posedge enable) begin
if (reset) begin
once_only <= 0;
end
else if (once_only == 0) begin
out <= calc_out; // or whatever processing you want
once_only <= 1;
end
end
always #(*) begin
// calculate ouput here always
calc_out = 1 + 7 +100+ in;
end
endmodule
You can't have those if statements calculate only once. It's hardware, it'll always calculate. But you can hold the output steady after it's been calculated once. You are still trying to write a software function and put it in to hardware rather than describe hardware which will solve your problem. I can't see that you'll get a decent design this way. Sure you'll be able to make some small pieces and synthesise them (eventually), but a full design??

Resources