Does not work as before Verilog initial construction in ModelSim Altera Edition 10.4 - verilog

Since version 10.4, start problem with initial block. Like this:
reg [31:0] init_ram[15:0];
initial begin
init_ram[0] = 32'h1234_5678;
init_ram[1] = 32'h8765_4321;
...
end
always_ff #(posedge clk)
init_ram[addr] <= data;
Or
module test(
input clk,
...
output reg a
);
initial a = 1'b1;
always #(posedge clk)
a <= ...;
ModelSim 10.4 error:
Error (suppressible): (vlog-7061) {path} Variable 'init_ram' driven in
an always_ff block, may not be driven by any other process
In older versions all works well.
You don't know which ModelSim parameter should I change to fix it?

One of the problems with the always_ff and always_comb constructs is that they are supposed to check the synthesizability during simulation, except that there is no standard for what is synthesizable. If the intent is that the initial blocks are just for simulation, then you will need to change the always_ff to always or change the initial block to use force/release instead.

One idea for a work around to your problem is to add a reset
signal and use it to initialize the value of a register.
Well, probably this
would be a good way to give an initial value to your flip-flops.
This should be something like:
reg [31:0] init_ram[15:0];
input reset;
always_ff #(posedge clk) begin
if (reset) begin
init_ram[0] <= 32'h1234_5678;
init_ram[1] <= 32'h8765_4321;
end
else begin
init_ram[addr] <= data;
Or this:
module test(
input clk,
input reset,
...
output reg a
);
always #(posedge clk) begin
if (reset) begin
a <= 1'b1;
end
else begin
a <= ...;

Related

Basic unit testing

I'm an experience programmer but new to HDL. I'm trying to figure out how to implement basic unit testing for my hardware designs for a class I'm taking. I'm aware of SVUnit, but I need to submit the code so I would prefer to just implement the barebones testing functionality myself. This will also help me learn more.
I'm having trouble figuring out what language constructs to use. All I really need to do is instantiate a component, drive the inputs, then verify the output values. The verification is where I'm stuck. Does that need to go into an always block?
Even pointing me in the right direction for what terms I should be googling would be very helpful. So far I've tried: verilog modelsim unit testing, verilog modelsim self-checking testbench, etc without too much success.
EDIT: Example:
Let's say I have a design for a 1 bit half adder. How would I write a testbench to exercise every possible input combination, and automatically verify that the output is correct?
As a first draft I would look at something like this.
reg clk = 0;
reg rst_n;
initial
begin
rst_n = 'bx;
#5
rst_n = 1'b0;
#20
rst_n = 1'b1;
end
always #(clk)
begin
clk = #10 ~clk;
end
reg a,b;
wire adder = a + b;
task test;
input i0,i1,o;
a = i0;
b = i1;
#1
if (adder !== o)
$display("Error:Incorrect output");
endtask
initial
begin
wait(rst_n === 1'b0);
#(posedge clk)
test(0,0,0);
#(posedge clk)
test(0,1,1);
#(posedge clk)
test(1,1,0);
#(posedge clk)
test(1,0,1);
end
Then you might as a second draft implement test data as something like:
wire [3:0] stim_data [1:0];
wire [3:0] expected_output;
always #(posedge clk)
if (!rst_n)
begin
cnt <= 2'b00;
end
else
begin
cnt <= cnt + 1;
end
assign {a,b} = stim_data[cnt];
always #(posedge clk)
if (!rst_n)
begin
end
else
begin
if (adder !== expected_output[cnt])
// add error message
end
Hopefully that should get you started.

Asynchronous reset D flipflop code syntax error

I'm writing a code to implement an asynchronous reset D flipfip, but the always# line is showing a syntax error:
`timescale 1ns / 1ps
module Dflipflop(
input D,
input reset,
input clk,
output Q
);
reg Q;
initial
begin
if(reset==1) //clear the output (Q=0)
begin
Q <= 0;
end
else if(reset==0)
begin
always#(posedge clk) //syntax error here...
begin
Q <= D;
end
end
end
endmodule
What could be the possible error, and is there a better logic for implementing the same ?
First of all I would not encourage you to use the initial statement except in testbench. This is not synthetizable so it should not appear in RTL.
Then I think you are confusing Verilog with a standard programming language which it is not.
In Verilog, there is two classes of statements:
processes, like always or initial
assignment, with assign that allows you to directly assign a 'value' to a wire
In processes there can be distinguished two classes :
Synchronous processes, //do something statements begin end will be evaluated only when an edge, specified in the #, occurs
always # (posedge clock) begin
//do something
end
Combinatorial processes, //do something statements will be evaluated every time the value of a wire or reg used in the //do something block changes
always #* begin
//do something
end
Here you have instantiated a process inside a process something that has no physical reality.
Another point, as described you want to activate the process only when reset==0 so you put a condition to enter the process. Once more, that does not make any sense in terms of synthesis. The process should be activated and that is in the process that the conditions should be evaluated.
A classical solution for implementing a D flip-flop with asynchronous reset is the following:
module Dflipflop(
input D,
input reset,
input clk,
output reg Q
);
always # (posedge clk or negedge reset) begin
if (!reset)
Q <= 1'b0; // Clear Q when reset negative edge occurs
else
Q <= D; // Capture D in Q when clk positive edge occurs and reset is high
end
endmodule
You cannot have always block inside initial. It should be written like this:
`timescale 1ns / 1ps
module Dflipflop(
input D,
input reset,
input clk,
output Q
);
reg Q;
always #(posedge clk, posedge reset)
begin
if(reset==1) //clear the output (Q=0)
begin
Q <= 0;
end
else
begin
Q <= D;
end
end
endmodule
You should either use initial(not recommended for synthesis) or always. One procedural block cannot come inside another. If you are really interested in designing a non-synthesizable logic and want to try out with initial, you can do something like this mentioned below. Both initial and always are procedural blocks.
....
else if(reset==0)
begin
repeat(100000) #(posedge clk)
begin
Q <= D;
end
end
end

D-flip flop with 2 reset: synthesis error

I'm doing a synthesis of a digital block and I need a D-Flip-Flop with 2 asynchronous resets.
(The reason is that I will drive one reset with an available clock, and I will use the second one to reset all the registers of my digital block)
I prepared the following code:
module dff_2rst(q,qn,clk,d, rst,clear);
input clk,d, rst, clear ;
output q,qn;
reg q,qn;
always #(posedge clk or posedge rst or posedge clear) //asynchronous reset
begin
(* full_case, parallel_case *)
case({rst, clear})
2'b00: begin
q <= d;
qn<=~d;
end
default: begin
q <= 1'b0;
qn <=1'b1;
end
endcase
end
endmodule
But I get the following error:
The statements in this 'always' block are outside the scope of the synthesis policy. Only an 'if' statement is allowed at the top level in this always block. (ELAB-302)
*** Presto compilation terminated with 1 errors. ***
I also tried with
if(~rst & ~clear)
but I have errors too.
Do you have an idea to correct my code? Thanks a lot!
The standard way to write a async reset, set (clear) flip-flop in Verilog RTL is:
always #(posedge clk or posedge rst or posedge clear) begin
if (rst) begin
// Aysnc Reset
q <= 'b0 ;
end
else if (clear) begin
// Async Clear
q <= 'b0 ;
end
else begin
// Sync logic here
q <= d;
end
end
assign qn = ~n;
The little trick for qn requires it qn be a wire, currently defined as a reg. reg q,qn; should just be reg q;
Also for cleaner code a new header type is cleaner and avoids repetition:
module dff_2rst(
input clk,
input d,
input rst,
input clear,
output reg q,
output qn );
Thank you Morgan. Your code was inspiring to me. I couldn't use
assign qn=~q;
Because I got the error:
qn is not a valid left-hand side of a continuous assignment.
But I modified your code in the following manner and it works:
module dff_2rst(q,qn,clk,d, rst,clear);
input clk,d, rst, clear ;
output q,qn;
reg q,qn;
always #(posedge clk or posedge rst or posedge clear) //asynchronous reset
//
begin
if (rst) begin
// Aysnc Reset
q <= 'b0 ;
qn<= 'b1 ;
end
else if (clear) begin
// Async Clear
q <= 'b0 ;
qn<= 'b1 ;
end
else begin
// Sync logic here
q <= d;
qn<= ~d;
end
end
endmodule

How to assign a register to an output in verilog?

I'm having difficulty figuring out how to assign the value of temp to the out. I searched the web for an answer and tried all kinds of things but still cannot get the output assigned. Here's the code:
module Reg8bit(
input CLK,
input En,
input CLR,
input [7:0] in,
output [7:0] out
);
reg[7:0] temp;
always #(posedge CLK)
begin
if (En)
begin
if (CLR)
out = 8'b0000_0000;
else
out = in;
end
end
assign out = tempQ;
endmodule
Edit: temp should be tempQ, sorry for the typo
You probably meant to write
module Reg8bit(
input CLK,
input En,
input CLR,
input [7:0] in,
output reg [7:0] out // out is a variable, not a wire
);
always #(posedge CLK)
begin
if (En)
begin
if (CLR)
out <= 8'b0000_0000; // use Non-blocking assignments
else
out <= in;
end
end
endmodule
Your code doesn't make much sense. You are assigning to out twice and your not using your temp register.
You probably meant to write something like this:
reg[7:0] temp;
always #(posedge CLK)
begin
if (En)
begin
if (CLR)
temp <= 0;
else
temp <= in;
end
end
assign out = temp;
Its usually (not always) considered good practice to use nonblocking assignments in always blocks. I think in this case you can even do this without the temp register.
The LHS of the assign statement should always be a wire. You have declared out as a reg and it's good to use a reg data type in the LHS inside an always block.

Syntax error near "posedge"

i'm trying to make the change the state at every posedge of clk and posedge of sclk and the compiler is throwing error at posedge.
module spi(output mosi,
input miso,
input dbus,
input sclk,input cs,
input clk,
input rst_b);
reg [1:0] state;
reg [1:0] next_state;
else if (posedge clk && posedge sclk) begin
state <= next_state;
if(clr == 0)
count <= 0;
else if(inc == 1)
count <= count +1;
There's a couple things wrong with this. Firstly, why are you using two clocks "clk" and "sclk" and ANDing them together? Just use one. Secondly, this all should be inside an always block. Don't use posedge with an if statement.
E.g.
always # (posedge clk)
begin
// do stuff

Resources