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.
Related
I am working on RTL coding of rs232 protocol in verilog I wrote the Tx/Rx codes in two different files.
I wanted to know whether these lines[as shown below] are legal in verilog. By legal I mean do they produce synthesizable output? I have initialized count_tx to 12. Basically, I want serial output through dataframe_tx. I know we can do this through the logical shift left, but I used this method.
In the waveform analyzer, I could see dataframe_tx always zero. That is where I started doubting these lines.
.
.
.
S_SENDING:begin
dataframe_tx = temp_tx[12-count_tx];
count_tx = count_tx - 1;
if(count_tx)
next_tx = S_SENDING;
else begin
next_tx = S_DONE;
done_tx = 1'b1;
end
end
.
.
.
.
To answer your question: The code fragment you posted consists of legal SystemVerilog constructs.
If one adds proper declarations of the objects you are referencing, adds the obvious missing case statement and wraps the whole in an always_ff block it will compile and thus generate synthesizable code.
You asked about syntax and not semantics. Will it work? Hard to tell from the fragment. But the intent of your if statement seems to be checking if the vector is non-zero. Consider if( |count_tx ) instead.
I added few lines to your code to make if syntactically OK. I also tool the liberty to change the assignments to non-blocking as these would be otherwise inferred by the tool. Still remains as a fragment but I hope it may help.
module Sandbox(
input logic clk
// inputs and outputs ...
);
logic dataframe_tx;
logic [12:0] temp_tx;
logic done_tx;
logic [3:0] count_tx;
enum {S_SENDING, S_DONE} next_tx;
always_ff #(posedge clk) // as an example
begin
case (next_tx)
// something ...
S_SENDING: begin
dataframe_tx <= temp_tx[12-count_tx];
count_tx <= count_tx - 1;
if( |count_tx )
next_tx <= S_SENDING;
else begin
next_tx <= S_DONE;
done_tx <= 1'b1;
end
end
// something ....
S_DONE: /* your code */;
endcase
end
endmodule
Good luck!
I am using two always block in the same module. Will it cause an error to synthesizable code? The source code is written in Verilog given below
module Mux (input wire[7:0] iterate, input wire deterministicEnable, input wire bistMode, input wire enable, input wire clk, input wire rst, output reg[127:0] valueO);
reg [9:0] seedVal[0:2];
reg[31:0] generatePattern [0:3],temp;
integer i;
always begin
#(deterministicEnable)begin
if(deterministicEnable==1)begin
temp<={22'b000000000000,seedVal[iterate]};
end
end
end
always#(posedge clk)begin
if(rst)begin
temp<=32'b11111111111111111111111111111111;
seedVal[0]<=10'b1001100101;
seedVal[1]<=10'b1111111111;
seedVal[2]<=10'b0000011111;
generatePattern[0]<=32'b00000000000000000000000000000000;
generatePattern[1]<=32'b00000000000000000000000000000000;
generatePattern[2]<=32'b00000000000000000000000000000000;
generatePattern[3]<=32'b00000000000000000000000000000000;
end
else begin
if((bistMode==1) && (enable==1))begin
for(i=0;i<4;i=i+1)begin
temp = {(temp[31] ^ temp[25] ^ temp[22] ^ temp[21] ^ temp[15] ^ temp[11] ^ temp[10] ^ temp[9] ^ temp[7] ^ temp[6] ^ temp[4] ^ temp[3] ^ temp[1] ^ temp[0]), temp[31:1]};
generatePattern[i] = temp;
end
valueO = {generatePattern[3],generatePattern[2],generatePattern[1],generatePattern[0]};
end
end
end
endmodule
As David suggested, this is not synthesizable because you drive temp from 2 different always blocks. To make it working, you need to combine both of them into a single one.
the first always is a complete mess which will behave as a messed-up flop in simulation due to truncated sensitivity list. Even if a synthesis tools would do something with the block, the result will not match simulation.
The second block might be synthesizable, but it will probably behave differently in hardware than in simuilation due to mixed use of blocking/non-blocking assignments for the same vars.
So, what to do.
you need to create a single always block out of 2 of them. It is difficult to see what your intent is, but in general it will probably look like:
always #(posedge clk) begin
if (rst) ...
else if (deterministicEnable) ...
else if if((bistMode==1) && (enable==1)) ..
end
it seems that both temp and generatePattern are internal variables and they do not need any reset. So, remove them from the if (rst) cluase. I do not see a need for temp at all in your code. You can remove it completely. There is also no use for the seedVal, so i do not see why you initialize them at all.
you are correct by using blocking assignments (=) for assigning to temp and to generatePattern, because they are internal vars. However value0 is not internal and you should have used an nba (<=) to assign. For that reason the value0 variable should be initialized with the rst signal, it is not.
No, this is not synthesisable, an always block creates a driver for all the signals assigned in it and each signal must always have only one driver (ignoring some exceptions for tristate not relevant here).
always begin
#(deterministicEnable)begin
is also not synthesisable as far as I know. If you want a combinational (not clocked), use always #* begin.
When I try to synthesize my verilog project i get the following errors:
ERROR:Xst:2634 - "shiftman.v" line 15: For loop stop condition should depend on loop variable or be static.
ERROR:Xst:2634 - "shiftman.v" line 22: For loop stop condition should depend on loop variable or be static.
I think I understand what causes the error, but I can't find a way to fix it.
module shiftman(in,sh,out);
input[47:0] in;
input[8:0] sh;
output[47:0] out;
reg[47:0] out;
reg[7:0] r;
reg i;
always#(in or sh)
begin
r=sh[7:0];
out=in;
if(sh[8]==0)
for(i=0; i<r; i=i+1)
begin
out[23:0]={1'b0,out[23:1]};
end
else
for(i=0; i<r; i=i+1)
begin
out[47:24]={1'b0,out[47:25]};
end
end
endmodule
The reason your synthesis is failing is because you cannot uses variable-iteration loops in synthesizable code. When synthesizing, the tool will attempt to unroll the loop, but it cannot do this if the termination condition for the loop is not static or determinable at synthesis. Your condition i <= r is such a condition as we cannot unroll the loop without knowing r, which is an input to the module and thus, not static.
In order to fix this, youll need to rewrite your code in a way that the synthesis tool can process. By the looks of it, you are simply logically shifting either the top or bottom of in by sh[7:0] depending on sh[8]. In order to do this, you don't need looping at all, but can use the >> (logical right shift operator). So, your always block would look more like this:
always #(*) begin
out = in;
if (sh[8])
out[47:24] = in[47:24] >> sh[7:0];
else
out[23:0] = in[23:0] >> sh[7:0];
end
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.
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