I am getting error when check my systemverilog code in quartus II - hardware

I have this simple code checked with Quartus II. First, It gives me error 5000 iterations for loop limit then I try to change verilog constant loop limit variable in settings and now it is giving me this error
Error (293007): Current module quartus_map ended unexpectedly. Verify that you have sufficient memory available to compile your design. You can view disk space and physical RAM requirements on the System and Software Requirements page of the Intel FPGA website (http://dl.altera.com/requirements/).
Is this something related to tool limitation or am I doing something wrong with my code ?
Here is my code:
module Branch_status_table #(parameter BST_length = 16383) //16383
(
output reg [2:1] status,
output reg [32:1] PC_predict_o,
input wire [2:1] status_update,
input wire [32:1] PC_in, PC_update,
input wire [32:1] PC_predict_update,
input wire clk,en_1,RST
);
wire [14:1] PC_index, PC_index_update;
//Internal memory
reg [2:1] status_bits [BST_length:0];
reg [32:1] PC_predict [BST_length:0];
reg [16:1] PC [BST_length:0];
//Combinational
assign PC_index = PC_in [16:3];
assign PC_index_update = PC_update [16:3];
//
initial begin
for ( int i=0; i <= BST_length; i=i+1) begin
status_bits[i] <= 0;
PC_predict[i] <= 0;
PC[i]<=0;
end
end
//Prediction
always_ff #(posedge clk) begin
if ( (PC[PC_index]==PC_in[32:17]) && (status_bits[PC_index]!=0) ) begin
status <= status_bits [PC_index];
PC_predict_o <= PC_predict [PC_index];
end
else begin
status <= 0;
PC_predict_o <= 0;
end
end
//Update
always_ff #(posedge clk) begin
if (en_1==1) begin
status_bits[PC_index_update] <= status_update;
PC [PC_index_update] <= PC_update[32:17] ;
PC_predict[PC_index_update] <= PC_predict_update;
end
else begin
status_bits[PC_index_update] <= status_bits[PC_index_update] ;
PC [PC_index_update] <= PC [PC_index_update] ;
PC_predict[PC_index_update] <= PC_predict[PC_index_update] ;
end
end
endmodule

There a coding issue and maybe a resource utilization issue.
The coding issue:
The code infers block ram, and is attempting initialize/reset it.
In general you can't reset block rams using a single initial block.
That style of initialization of arrays can be done in a testbench, not in RTL.
Synthesis tools have physical limits.
To reset/initialize a block ram you must write 0 to each address. Use the same type of synchronous process (always #(posedge clk)) because the memory is a synchronous device. Put a mux in front of the write port and use a state machine a start up to write 0's to every address, then when the state machine finishes the state that move to an state where the BRAM behaves like you normally want it to.
This page discusses the issue.
https://www.edaboard.com/threads/how-to-clear-reset-my-bram-in-vhdl-xilinx.247572/
This is a Xilinx related answer; other vendors work the same way.
Summarizing the coding issue: You probably don't need to initialize and you can't do it this way:
initial begin
for ( int i=0; i <= BST_length; i=i+1) begin
status_bits[i] <= 0;
PC_predict[i] <= 0;
PC[i]<=0;
end
end
Potential Utilization Issue:
FPGAs' have finite resources.
The tool seems to be indicating that the code infers more block ram than the part has. To verify this, change parameter BST_length from 16K to something small like 8 and see if the utilization issue ("insufficient memory") goes away. If it goes away then re-design using less memory.
This can also be analyzed by hand knowing how much BRAM the part has and how much you are inferring. Don't infer more than the part has.
The tool is giving different answers with simple code changes because of two issues related to the same inference of BRAM. When the code changes a little the tool switches and informs about the other issue. This is how the tools work sometimes, a first error can mask a second by erroring out so that the 2nd error is not reached.

Related

When I add memory clear logic Bram memory turn into distributed ram

I want to create a BRAM that has a data clear logic. With saying that I mean after a reset signal all the data inside of the BRAM needs to be 0.
I coded BRAM in verilog HDL.
(* ram_style = "block" *)
reg [7:0] mem [511:0];
reg [7:0] data_read = 8'b0;
always#(posedge clk) begin
if (write_i) begin
mem[addr_i] <= write_data_i;
end
else begin
data_read <= mem[addr_i];
end
end
assign read_data_o = data_read;
This code block successfully generates BRAM as netlist can be shown in the following image:
But when I add reset logic to BRAM to clear the data inside of it when reset rises, BRAM memory turns into distributed RAM.
This is the data clear logic I have added:
if (rst) begin
for(i=0; i<512 ; i= i+1) begin
mem[i] <= 8'b0;
end
end
Netlist after I added clear logic:
What is the reason of this? Why BRAM becomes distributed Ram? Isn't it possible to create a BRAM with data clear logic ?
The vendor BRAM macro/primitives/hardware do not support a global clear/write 0, or write anything else using a control signal.
See
https://docs.xilinx.com/v/u/2019.2-English/ug901-vivado-synthesis
section 4 for supported RAM inference coding styles.
There are two ways to accomplish some sort of BRAM initialization or global write.
Use a state machine controller to loop thru all the addresses
and assign the values needed (write to the ram in a controlled way using RTL to control the address, data, and wr_en)
Use Vivado IP catalog (or ISE Coregen) generated RAM and a .mif/.coe file. The contents of the .mif/.coe get loaded one time when the FPGA is configured.
More info on using .mif files here:
https://docs.xilinx.com/r/en-US/ug896-vivado-ip/IP-User-Files-ip_user_files-for-Core-Container
The memory generator GUI provides the opportunity to load a .coe file. The .coe is used for synthesis, .mif file for simulation.
If you want to use the generated IP method see:
https://docs.xilinx.com/v/u/en-US/pg058-blk-mem-gen
My preference is a state machine, so that external files and external IP are not needed.

Passing values to module instance port through loops inside always block in verilog

I need to access ports of module instance through for loop using verilg code, i'm trying to send inputs to a module instance repeatedly hoping every time the output for corresponding input get updated, unfortunately it is not happening because the inputs get passed only after execution exit the procedural block, please find the below code and let me know the possibilities, thanks in advance.
integer i,j;
always#(g_mtx,gi_mtx)
begin
for (i=1;i<3;i=i+1)
for (j=1;j<3;i=j+1)
if(i!=j)
begin
L_in1=g_mtx[j][j];
L_in2=gi_mtx[i][i];
L_in3=gi_mtx[j][i];
L_in4=g_mtx[j][i];
Lmd[i][j]= L_out ;
end
end
Lamda_top lmd (L_out,L_in1,L_in2,L_in3,L_in4,clk);//instance
//here g_mtx,gi_mtx,Lmd are memories.
The solutions differ depending on the context.
If this is for a testbench, all you need do is add some form of delay after simulating the inputs. Seeing as you are using a clock for the Lamda_top module, you can use the same clock as the delay source to ensure enough time has passed:
always #(g_mtx,gi_mtx) begin
for (i=1; i<3; i=i+1) begin
for (j=1; j<3; j=j+1) begin
if(i!=j) begin
L_in1=g_mtx[j][j];
L_in2=gi_mtx[i][i];
L_in3=gi_mtx[j][i];
L_in4=g_mtx[j][i];
repeat ([number of cycles it takes for Lamda_top to finish]) begin
#(posedge clk);
end
#(negedge clk); // Ensure L_out has gotten the value from the function
Lmd[i][j] = L_out;
end
end
end
end
However, if this is instead for actual, synthesizable code, you will need to implement some sort of FSM to serialize the for-loops to only input one set of L_inX variables at a time.
Ultimately, both solutions involve ensuring that only one set of L_inX is passed through for each clock. Without knowing more context, its hard to say how best to handle this (should probably be some sort of pipeline, but thats alot more work to patch the provided code to implement)

Verilog module for a smoke detector and a buzzer

I have Altera DE2-115 FPGA and I try to self-learn Verilog. I decided to make a smoke detector and whenever it smells smoke the buzzer rings (the smoke detector outputs a digital signal).
Here is my trial :
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm;
wire fire;
reg [2:0] fire_state;
assign firealarm = (fire_state == 1) ? (flag ? 0 : 1) : 0;
always # (posedge clock)
fire_state<= fire ? 1: 0;
end module
But it doesn't run and I think there are a lot of logic errors in this code, any help please? :)
endmodule is one word, you need to remove the space.
Almost all simulators these days support verilog-2001 or greater so I would encourage the use of the modern port style (ANSI) and not the old verilog 1995 style.
Your port list goes from:
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm; wire fire;reg[2:0] fire_state;
to :
module fire(
input clock,
input reset,
input flag,
input fire,
output reg [2:0] fire_state,
output firealarm
);
I have placed each port on a new line with it direction, this makes it much easier to maintain code, it also make it a lot more readable and therefore minimises the chance of typos in connections.
You have used this syntax a lot (flag?0:1), where you using a boolean to select a boolean there is no need to do this and makes it more difficult to read. If you need to invert it then is a bitwise invert (~). However it is not clear what you are using flag for.
for comparrisons and assignments you should be including the width.
assign firealarm = (fire_state == 3'b1)? (~flag) : 1'b0;
This could also be written out in a combinatorial always block:
always #* begin
if (fire_state==3'b001) begin
firealaram = ~flag;
else begin
firealaram = 1'b0;
end
end
fire is 1 bit, fire_state is 3 bits.
always # (posedge clock) begin
fire_state <= {2'b0, fire};
end

Can SystemVerilog represent a flip-flop with asynchronous set and reset without adding unsynthesizable code?

I'm coming from a Verilog-95 background, and I'm trying to figure out what Verilog-95 hoops I don't have to jump through anymore.
The obvious way to write a flip flop with async set and reset in Verilog-95 is:
always #(posedge clk or negedge resetb or negedge setb) begin
if (!resetb) q <= 0;
else if (!setb) q <= 1;
else q <= d;
end
This works in synthesis. But, this doesn't work in simulation if we ever assert both resetb and setb, and then de-assert resetb before de-asserting setb, since there's no posedge trigger for either of those signals. We need to add the following (which varies depending on your synthesis tool), to get simulation to match synthesis:
// synopsys translate_off
always #(resetb or setb)
if (resetb && !setb) force q = 1;
else release q;
// synopsys translate_on
Is there a SystemVerilog construct that will let you do this without this extra junk? Better yet, is there a straightforward way to do it in Verilog-95?
Flip-flops with multiple asynchronous controls are best avoided. The timing checks necessary to ensure they function properly are complex and easy to mess up. If you really need to use them, then it's probably best to instantiate them by hand where needed. If you let your synthesis tool infer them, it may use them in places you don't intend, which increases the risk that the timing checks don't get done properly.
One final aside, there is a similar simulation-synthesis mismatch issue with all asynchronous flops, if the active edge of reset is at time zero and is simulated before the flop is initialized to x, and the clock isn't running in reset. I believe some simulators have special cases to ensure the logic is not initialized in this order.
That said, I had luck moving the priority logic outside the sequential always block. Note I'm using active-high signals for simplicity.
assign s_int = s && !c;
always #(posedge clk or posedge s_int or posedge c) begin
if (c)
q <= 1'b0;
else if (s_int)
q <= 1'b1;
else
q <= d;
end
This is something I wish SystemVerilog had improved. If you want to allow both being low at the same time, then stick with the current method.
The other option is to create a design rule stating the asynchronous signals can not be active at the same time and enforce the rule with an assertion. Assertions are suppose to be ignored by synthesizers, so translate_off/on should not be be necessary.
Here is an example using an inline assertion:
always_ff #(posedge clk, negedge resetb, negedge setb) begin : dff_asyncRbSb
if (!resetb) q <= 0;
else if (!setb) q <= 1;
else q <= d;
asrt_setrst : assert(resetb||setb)
else $error("resetb and setb can not be low at the same time.");
end : dff_asyncRbSb
I don't know any SV, so this isn't an answer, but the issue here is that
Verilog (and, I think, SV) event expressions are basically broken. The problem
is that, when you have multiple conditions in an event expression:
event_expression ::=
expression
| hierarchical_identifier
| posedge expression
| negedge expression
| event_expression or event_expression
| event_expression , event_expression
then there's no bullet-proof way to determine which expression caused the
event, since the only thing you can do is to check the current state of the
expression. So, if you've got #(posedge clk, posedge rst), for example, you
look at the current levels of clk and rst and hope this is sufficient to do
the job. In general, it isn't, but your example is the only practical case (I
think) that causes a problem.
VHDL handles this by having signal attributes, which let you determine whether
a signal has caused an event. In VHDL, you get an event when any signal in
your sensitivity list changes, and you then check their 'event attribute to
determine whether they fired the process. No confusion, no posedge or negedge,
and it all works.
I've just had a quick look at the SV LRM, and SV attributes appear to be the
same as Verilog attributes, so I think you're out of luck.
with no edge defined, the assertion and de-assertion of reset and set signals should be able to trigger this code in simulation.
always_ff should be able to create a flop at synthesis.
Below code is compilation clean using synopsys VCS tool.
always_ff #(posedge clk, resetb, setb) begin
if (!resetb) q <= 0;
else if (!setb) q <= 1;
else q <= d;
end
Try this:
always_ff #(posedge clk or negedge resetb or negedge setb)
systemverilog uses always_ff for clock triggered logic and always_comb for combo logic

signal vs variable

VHDL provides two major object types to hold data, namel signal and variable, but I can't find anywhere that is clear on when to use one data-type over the other. Can anyone shed some light on their strengths/limitations/scope/synthesis/situations in which using one would be better than the other?
Signals can be used to communicate values between processes. Variables cannot. There are shared variables which can in older compilers, but you really are asking for problems (with race conditions) if you do that - unless you use protected types which are a bit like classes. Then they are same to use for communication, but not (as far as I know) synthesisable.
This fundamental restriction on communication comes from the way updates on signals and variables work.
The big distinction comes because variables update immediately they are assigned to (with the := operator). Signals have an update scheduled when assigned to (with the <= operator) but the value that anyone sees when they read the signal will not change until some time passes.
(Aside: That amount of time could be as small as a delta cycle, which is the smallest amount of time in a VHDL simuator - no "real" time passes. Something like wait for 0 ps; causes the simulator to wait for the next delta cycle before continuing.)
If you need the same logic to feed into multiple flipflops a variable is a good way of factoring that logic into a single point, rather than copying/pasting code.
In terms of logic, within a clocked process, signals always infer a flipflop. Variables can be used for both combinatorial logic and inferring a flipflop. Sometimes both for the same variable. Some think this confusing, personally, I think it's fine:
process (clk)
variable something : std_logic;
if rising_edge(clk) then
if reset = '1' then
something := '0';
else
output_b <= something or input c; -- using the previous clock's value of 'something' infers a register
something := input_a and input_b; -- comb. logic for a new value
output_a <= something or input_c; -- which is used immediately, not registered here
end if;
end if;
end process;
One thing to watch using variables is that because if they are read after they are written, no register output is used, you can get long chains of logic which can lead to missing your fmax target
One thing to watch using signals (in clocked processes) is that they always infer a register, and hence leads to latency.
As others have said signals get updated with their new value at the end of the time slice, but variables are updated immediately.
// inside some process
// varA = sigA = 0. sigB = 2
varA := sigB + 1; // varA is now 3
sigC <= varA + 1; // sigC will be 4
sigA <= sigB + 1; // sigA will be 3
sigD <= sigA + 1; // sigD will be 1 (original sigA + 1)
For hardware design, I use variables very infrequently. It's normally when I'm hacking in some feature that really needs the code to be re-factored, but I'm on a deadline. I avoid them because I find the mental model of working with signals and variables too different to live nicely in one piece of code. That's not to say it can't be done, but I think most RTL engineers avoid mixing... and you can't avoid signals.
Other points:
Signals have entity scoping. Variables are local to the process.
Both synthesize