Quartus Error (10028) with memory - verilog

My goal is to form this code with Quartus, but the problem is I don't know how to fix the problem.
I've tried to know what Error 10028 means, but I cant figure out how to work with it.
Can someone teach me how to fix it or if there's a way to bypass it?
module mem (r_wb,addr,d,q);
input r_wb;//0write 1read
input [7:0] addr;
input [7:0 ] d;
output [7:0] q;
reg [7:0] q;
reg [7:0] mem_bank [0:255];
always #(r_wb)
if (r_wb) q=mem_bank[addr];
else mem_bank[addr]=d;
always #(addr)
if (r_wb) q=mem_bank[addr];
else mem_bank[addr]=d;
always #(d)
if (r_wb) q=mem_bank[addr];
else mem_bank[addr]=d;
endmodule

The code you put in your comment is mostly correct in the fact that you do need a clocking signal. However you should be using non-blocking assignment (<=).
I would recommend changing your model header to ANSI style which has been around since 2001. The non-ANSI style required q the be identified three times; port list, direction, type. ANSI style compacts it. Non-ANSI is good to understand because a lot of synthesizers and code generators still use it by default. But any modern simulator or synthesizer will accept ANSI style as input.
module mem (
input clk,
input r_wb, //0write 1read
input [7:0] addr,
input [7:0 ] d,
output reg [7:0] q) ;
reg [7:0] mem_bank [0:255];
always #(posedge clk)
if (r_wb) q<=mem_bank[addr];
else mem_bank[addr]<=d;
endmodule

Related

Simple assignment of wire to output led in verilog doesn't synthesis with yosis

The following code will not build exiting with Error Code -6
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = wire1;
endmodule
But making this small change builds properly. Can you not just assign a wire to an output without modifying it in some way?
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = ~wire1;
endmodule
I've seen this before. Some synthesis tools don't handle well the case of there being zero gates in the design, as that means there's zero die area needed before routing. I'm guessing the tool is hitting some internal divide-by-0.
So yes, you can simply connect a wire to an output. That by itself is perfectly valid. And you can even connect an input directly to an output. As long as you have any other gates in the design, even unrelated/unconnected to the ports/nets in your example, the synthesizer would be happy, as there'd be non-zero die area.
So I bet this would work fine:
module and_gate (
input [1:0] io_button,
output [2:0] io_led
);
wire wire1;
assign wire1 = io_button[0];
assign io_led[0] = wire1;
assign io_led[1] = ~io_button[1]; // added line, just to infer a gate somewhere
endmodule

Wire with multiple modules

I am trying to simulate a really basic memory model by having multiple memory blocks (initiations of a basic module) and tying the output of all those blocks to one wire. Is this the way to do this?
module memoryBlock(
input Enable,
output [7:0] dataOut,
input [7:0] dataIN
);
always #(*) begin
if(Enable == 1)
dataOut = dataIn;
end
endmodule;
The idea is that only one of these data blocks would be enabled at a time, and then I could pass whatever information was in the enabled block to the output wire. Here is how I would use it:
module testbench;
reg [7:0] exampleData1 = 8'b00000001;
reg [7:0] exampleData2 = 8'b11111111;
reg enable1 = 0;
reg enable2 = 1;
wire [7:0] outputForBoth;
memoryBlock mb1(enable1, outputForBoth, exampleData1);
memoryBlock mb2(enable2, outputForBoth, exampleData2);
endmodule;
When I have tried sample stuff like this before the output has just been 'zzzzzzzz'. My goal is to be able to have multiple memory blocks.. only enable one of them, and have that wire hold whatever data from that block. Is this the correct approach? Any help would be huge!
This way I only have one place I need to go to retrieve all of the output information. The other way I thought to do this was building a MUX of some sorts, and it just seems a lot more complicated that it needs to be!
You need tri-state outputs to do this. Tri-states drive a wire when enabled and are at high impedance state when not. But you need to make sure that you don't enable two modules at the same time.
module memoryBlock(
input enable,
inout [7:0] dataOut,
input [7:0] dataIN
);
assign dataOut = enable? dataIn : 8'bzzzzzzzz;
endmodule

Displaying a bus in Verilog

I'm writing a code in Verilog which would count till 15 on every edge of a clock and would go back to 0. However, I'm not able to display waveforms. All I can see is Z (high impedance).
`timescale 1ns / 1ps
module Counter(
input ck,
output [3:0] a
);
reg a;
reg [3:0] i = 4'b0000;
always#(posedge ck)
begin
a = i;
if(i==15)
i = 0;
else
i = i+1;
end
endmodule
Here is the testbench to drive it:
module Counter_tb;
wire clock;
wire [3:0] ta;
Clocker mygate(.clk(clock));
Counter mygate2(.ck(clock), .a(ta));
initial
begin
$display(ta, clock);
end
endmodule
The waveform of clock is displayed properly, but not ta. What could be the possible mistake?
You declared a twice, once as an 4-bit output (inferred wire type), and once a an internal single bit reg. The way you did it is non-compliant with the IEEE standard because is does not follow the ANSI or non-ANSI style. Some simulators may allow what you did and work correctly, others throw compiling errors (strict IEEE compliance), and some get confused. I'm guessing the latter is what happened with your simulator; maybe there was a warning message in your compile log you over looked.
Get rid of the line reg a; and change output [3:0] a to output reg [3:0] a to make it compatible with an ANSI style header. With an ANSI portlist style, the ports direction, type, width, and name are declared on the same name.
module Counter(
input ck,
output reg [3:0] a
);
The Alternative is the Non-ANSI style (not recommended), which is required one line for declaring the port order, another for the direction & size, and a optional additional line to make it a reg. A proper Non-ANSI style header below.The Non-ANSI style header is required with IEEE1364-1995. ANSI was added and became the recommended styles since IEEE1364-2001, with non-ANSI supported so legacy code could continue being used.
module Counter(ck, a);
input ck;
output [3:0] a;
reg [3:0] a;
Other note, flops should be assigned with non-blocking (<=) assignments, instead of blocking (=) assignments. At minimum change a = i; to a <= i; to get in the practice of proper coding style that will avoid race conditions in the verilog scheduler.
You call "$display" once at time 0. What you are expecting to see?
Try to change $display to "$monitor(ta, clock);".

Why does the following redeclaration error happen in verilog?

I'm trying to implement a simple verilog code as below:
module test1(
input ACLK,
input RST,
output test_output1,
output test_output2
);
//wire ACLK;
//wire RST;
reg test_output1;
reg test_output2;
assign test_output1 = ACLK;
always #(posedge ACLK or negedge RST)
begin
if(!RST)
begin
//test_output1 <=0;
test_output2 <=0;
end
else
begin
//test_output1 <=0;
test_output2 <=1;
end
end
endmodule
I get the following error message when I try to synthesize it in Xilinx ISE:
=========================================================================
* HDL Compilation *
=========================================================================
Compiling verilog file "test1.v" in library work
ERROR:HDLCompilers:27 - "test1.v" line 30 Illegal redeclaration of 'test_output1'
ERROR:HDLCompilers:27 - "test1.v" line 31 Illegal redeclaration of 'test_output2`
I am unable to resolve this error. Any help would be highly appreciated.
If you declare the directional of the port in the portlist, you must also declare the type. This is referred to as an ANSI style header.
There is also a non-ANSI style header that separates the portlist, directional, and type. If you are fallowing IEEE1364-1995 convention then you must use non-ANSI style and you cannot declare the type (e.g. output reg test_output2; is illegal, while output test_output2; reg test_output2; is legal). Since IEEE1364-2001 ANSI and non-ANSI style is supported (and the non-ANSI allows output reg test_output2;). All modern Verilog simulators are SystemVerilog (IEEE1800) simulators, therefore it is the designers choice. (ANSI style is more popular as it is less typing).
ANSI style header:
module test1(
input ACLK,
input RST,
output test_output1,
output reg test_output2 );
Non-ANSI style header:
module test1( ACLK, RST, test_output1, test_output2 );
input ACLK;
input RST;
output test_output1;
output test_output2;
reg test_output2;
Note: With IEEE1364, you can not drive a reg with an assign statement, it must be a net type. IEEE1800 has softened the rule the it is recommenced logic in stead of reg, but generally if you are going to use assign then you should be assigning a net (e.g. wire).
Add following modification:
You used test_output1 in assign statement so it should be of type wire.
module test1(
input wire ACLK,
input wire RST,
output wire test_output1,
output reg test_output2
);
You have already declared test_output1 and test_outpu2 as output and it is by default of type wire, so you just have to implicitly specify wire or reg according to usage,
// reg test_output1;
// reg test_output2;

Assign a synthesizable initial value to a reg in Verilog

I'm an FPGA noob trying to learn Verilog. How can I "assign" a value to a reg in an always block, either as an initial value, or as a constant. I'm trying to do something like this in the code below. I get an error because the 8 bit constant doesn't count as input. I also don't want to trigger the always off of a clock. I just want to assign a register to a specific value. As I want it to be synthesisable I can't use an initial block. Thanks a lot.
module top
(
input wire clk,
output wire [7:0] led
);
reg [7:0] data_reg ;
always #*
begin
data_reg = 8'b10101011;
end
assign led = data_reg;
endmodule
You can combine the register declaration with initialization.
reg [7:0] data_reg = 8'b10101011;
Or you can use an initial block
reg [7:0] data_reg;
initial data_reg = 8'b10101011;
You should use what your FPGA documentation recommends. There is no portable way to initialize register values other than using a reset net. This has a hardware cost associated with it on most synthesis targets.
The other answers are all good. For Xilinx FPGA designs, it is best not to use global reset lines, and use initial blocks for reset conditions for most logic. Here is the white paper from Ken Chapman (Xilinx FPGA guru)
http://japan.xilinx.com/support/documentation/white_papers/wp272.pdf
The always #* would never trigger as no Right hand arguments change. Why not use a wire with assign?
module top (
input wire clk,
output wire [7:0] led
);
wire [7:0] data_reg ;
assign data_reg = 8'b10101011;
assign led = data_reg;
endmodule
If you actually want a flop where you can change the value, the default would be in the reset clause.
module top
(
input clk,
input rst_n,
input [7:0] data,
output [7:0] led
);
reg [7:0] data_reg ;
always #(posedge clk or negedge rst_n) begin
if (!rst_n)
data_reg <= 8'b10101011;
else
data_reg <= data ;
end
assign led = data_reg;
endmodule
Hope this helps
When a chip gets power all of it's registers contain random values. It's not possible to have an an initial value. It will always be random.
This is why we have reset signals, to reset registers to a known value. The reset is controlled by something off chip, and we write our code to use it.
always #(posedge clk) begin
if (reset == 1) begin // For an active high reset
data_reg = 8'b10101011;
end else begin
data_reg = next_data_reg;
end
end

Resources