How to access text files at synthesis level - verilog

I am writing Verilog code using Lattice Diamond for synthesis.
I have binary data in a text file which I want to use as input for my code.
At simulation level we can use $readmemb function to do it. How is this done at synthesis level?
I want to access data present in text file as an input for FPGA.
As suggested by Mr Martin Thompson(answers below) I have written a Verilog code to read data from a file.
Verilog code is given below:-
module rom(clock,reset,o0);
input clock,reset;
output o0;
reg ROM [0:0];
reg o0;
initial
$readmemb("rom.txt",ROM);
always #(negedge clock,negedge reset )
begin
if(reset==0)
begin
o0<=0;
end
else
begin
o0<=ROM[0];
end
end
endmodule
When I am running this code on fpga I am facing the problem below:-
If text file which I want to read have only one bit which is '1' then I am able to assign input output pins to clock,reset and ROM. But if I have one bit which is '0' or more than one bits data in text file I am unable to assign input pins(i.e clock,reset) and a warning is displayed:-
WARNING: IO buffer missing for top level port clock...logic will be discarded.
WARNING: IO buffer missing for top level port reset...logic will be discarded.
I am unable to understand why I am getting this warning and how I can resolve it.

One way is to build the data into the netlist that you have synthesised. You can initialise a read-only memory (ROM) with the data using $readmemb and then access that as a normal memory from within your device.
Here's an introduction to some memory initialisation methods:
http://myfpgablog.blogspot.co.uk/2011/12/memory-initialization-methods.html
And in here:
http://rijndael.ece.vt.edu/schaum/slides/ddii/lecture16.pdf
is an example of a file-initialised RAM on the second to last slide. If you want just a ROM, leave out the if (we) part.

Think of Simulation as an environment not a level. You should just be switching the DUT (Device Under Test) from the RTL code to the synthesised netlist, other than this nothing should change in your simulation environment.
From the block of code you have given it does not look like you are separating out the test and code for the fpga. You should not be trying to synthesise your test I would recommend splitting it between at least 2 separate modules, your test instantiating the code you want to place on the fpga. Pretty sure the $fwrite is also not synthesizable.
A simple test case might look like:
module testcase
//Variables here
reg reg_to_drive_data;
thing_to_test DUT (
.input_ports ( reg_to_drive_data )
.output_ports ()
...
);
//Test
initial begin
#1ns;
reg_to_drive_data = 0;
...
end
endmodule
Via includes, incdir or file lists the code for thing_to_test (DUT) is being pulled in to the simulation, change this to point to the synthesised version.
If what you are trying to do is initialise a ROM, and hold this data in a synthesised design Martin Thompson's answer covers the correct usage of $readmemb for this.

Related

How can i writing test bench for multiple module?

I am new in this field,
I don't know if they've been asked before.
I'm writing code by creating separate modules to get used to big projects.
I have no problems creating modules, but I don't know how to create a testbench.So I should write test bench according to main module.
but the main module was created with reference to 3 separate modules.
How should be testbench of the following code?
Can you help me with this code?
//location of the main program
module circuit1_main(A,sel_m,Q);
input [2:0]A;
input sel_m;
output Q;
wire clk_m,reset_m,ud_m,load_m;
wire [2:0]A;
wire sel_m;
wire Q;
wire internal1;
wire internal2;
wire internal3;
wire internal4;
circuit1_counter cnt1(.clk(clk_m),.reset(reset_m),
.en(1'b1),.ud(ud_m),.load(load_m),
.d(A),.cnt(internal1));
assign internal2 = ~internal1;
circuit1_mux mux1(.a(internal1),.b(internal2),
.sel(sel_m),.out(internal3));
circuit1_shiftreg shiftreg1(.clk(clk_m),.reset(reset_m),
.sin(internal3),.sout(internal4));
assign Q = internal4;
endmodule
I have some bad new for you: You can't really write a test-bench for your 'circuit1_main' as it is rather broken.
Your module has a number of internal signals: clk_m,reset_m,ud_m,load_m; which should all come from outside. They should all be input ports which you must drive from your test bench.
I suspect, from the usage of the name 'main' that you are more comfortable with using C, C++ or other standard programming language. It is very important to realise that writing HDL is rather different. I therefore suggest you have a look around at some existing HDL code.
I know that the internet is full of HDL examples of FIFOs, UARTS, Counters etc., but that test benches are few and far between, Here is one which has code and the test benches that come with them.
I would also suggest you do not split your code into modules which are very, very small: Your circuit1_mux would be one line of code: assign out = sel ? a : b ;1 Writing a module and connecting it up is ten times more work then using that single line of code and less confusing. Is out equal to a or to b when sel_m is high?
1Substituting your port name could make it `assign internal3 = sel_m ? internal1 : internal2; which make immediately clear to anybody that sel_m selects the internal1 case.

How to initialize contents of inferred Block RAM (BRAM) in Verilog

I am having trouble initializing the contents of an inferred ram in Verilog. The code for the ram is as below:
module ram(
input clock, // System clock
input we, // When high RAM sets data in input lines to given address
input [13:0] data_in, // Data lines to write to memory
input [10:0] addr_in, // Address lines for saving data to memory
input [10:0] addr_out, // Address for reading from ram
output reg data_out // Data out
);
reg [13:0] ram[2047:0];
// Initialize RAM from file
// WHAT SHOULD GO HERE?
always #(posedge clock) begin
// Save data to RAM
if (we) begin
ram[addr_in] <= data_in;
end
// Place data from RAM
data_out <= ram[addr_out];
end
endmodule
I have run into the command $readmemh. However, documentation for it seems sparse. How should I format the file that contains the data? Also, how can I pass the file as argument when instantiating this module so that I can have different instances of this module load from different files?
I want the initialized content to be available for both simulation and actual implementation. So that the FPGA already boots with this content in RAM.
I am using Vivado 2015.4 to program a Kintex xc7k70 FPGA.
You are correct that you should use $readmemh inside an initial block. In order to make it so different instances of the module can have different initialization files, you should use a parameter like so:
parameter MEM_INIT_FILE = "";
...
initial begin
if (MEM_INIT_FILE != "") begin
$readmemh(MEM_INIT_FILE, ram);
end
end
The format is described in Section 21.4 of the IEEE1800-2012 specification; typically the file is just a bunch of lines containing hex numbers of the correct bit-length, like so:
0001
1234
3FFF
1B34
...
Note that there is no "0x" prefix and each line represents an adjacent address (or any separating whitespace). In the example above, $readmemh would put 14'h0001 into ram[0], 14'h1234 into ram[1], 14'h3FFF into ram[2] and so on. You can also include comments in the hex file using // or /* */. Finally, you can use the # symbol to designate an address for the following numbers to be located at, like so:
#0002
0101
0A0A
...
In the above file, ram[0] and ram[1] would be uninitialized and ram[2] would get 14'h0101. Those are all the major constructs of the hex file format, though you can also use _, x and z as you would in other Verilog numbers and theres a few more rules you can read in the section sited above.
Apart from #Unn's excellent ans, I want to add that, If you just want to initialize your memory with either all bits to 1'b1 or 1'b0, then you can just put following code,
integer j;
initial
for(j = 0; j < DEPTH; j = j+1)
ram[j] = {WIDTH{MEM_INIT_VAL}};
For your case, WIDTH=14, and MEM_INIT_VAL may be 1'b1 or 1'b0.
Since your question cited the #xilinx and #vivado tags, I wanted to suggest that you can also use the xpm_memory family of primitives to instantiate a parameterized memory. The advantages of this approach:
Exports exactly the hardware capabilities of the memory resources on the FPGA (ie, makes you think clearly about limitations such as memory ports).
Guarantees correct identical behavior in simulation and benchtop for memory primitives.
You can allow Vivado to choose the most efficient memory implementation (BRAM, UltraRAM, distributed RAM, flops) at synthesis time, according to your design constraints.
Easy to fine tune (enable or disable internal pipeline stages, etc.).
With that said, purely inferred memories are often easier to code. But, it's still worth getting familiar with the Xilinx-provided memory primitives so that you'll have a clearer idea of what Vivado can easily synthesize, and what it can't.
For more information, see UG573, the Vivado Memory Resources User Guide:
https://www.xilinx.com/support/documentation/user_guides/ug573-ultrascale-memory-resources.pdf
integer j;
initial
for(j = 0; j < DEPTH; j = j+1)
ram[j] = j;
This might be easy in case of debug, where the value of a location is its location number.
Also, I would suggest you to not initialize the RAMs. It will help you in catching bugs, if any, in simulation as the data driven will be 'x if RAM is un-intialized and can be caught easily.

WARNING:Xst:1290: - Hierarchical block <uut2> is unconnected in block <top>. It will be removed from the design

Here is my code of top module and rom module. I don't find any error in this, but it is showing this error and I don't know why.
module top (clk,clr, ss, mosi,sck);
input clk;
input clr;
output ss;
output mosi;
output sck;
wire [10:0]address;
wire[7:0]data;
wire done,start,mclk,clk_out;
clock uut1(.clr(clr),.mclk(clk),.clk_out(clk_out));
ROM_Memory uut2(.address(address),.data(data));
ctrl uut3 (.clr(clr),.clk(clk_out),.address(address),.data(data),.start(start),.done(done));
spi uut4 (.clk(clk_out),.clr(clr),.data(data),.start(start),.done(done),.ss(ss),.mosi(mosi),.sck(sck));
endmodule
ROM module-
module ROM_Memory(address,data);
input [10:0] address;
output [7:0] data;
reg [7:0]ROM[0:1034];
initial begin
$readmemh("preeti.txt",ROM);
end
assign data = ROM[address];
endmodule
It is showing rest three modules in RTL schematic and simulation is also running fine.
Your top module serves as a framework to connect things one each other.
Your system seems to be a controller that reads a ROM and sends its contents thru SPI. The ROM is effectively connected in top, but your module only shows that there are a pair of buses (address and data) which ROM is connected to. We don't know if those buses are connected to somewhere else. They should be, but if ctrl or spi don't use address or data (because of a mispelled name, for example), the ROM will actually be connected to nowhere.
Add this to the beginning of every Verilog file in your design, so you can catch any error caused by a mispelled signal name:
`default_nettype none
Another cause of your ROM being disconnected from your design is that the file you provide to initialize it is not complete. If your ROM has 1035 cells, all of them must be initialized, or else, the synthesizer will throw away the ROM register, and hence, the complete ROM_Memory module will be thrown away as well.
To ensure that your ROM is totally initialized, modify your initial block to add these lines:
integer i;
initial begin
for (i=0;i<=1034;i=i+1) // Prefill all the ROM, so you can use an incomplete file later
ROM[i] = 8'h00;
$readmemh("preeti.txt",ROM); // Initialize up to 1035 cells from preeti.txt
end

Snake game using FPGA (ALTERA)

I am planning to make a snake game using the Altera DE2-115 and display it on LED Matrix
Something similar to this in the video http://www.youtube.com/watch?v=niQmNYPiPw0
but still i don't know how to start,any help?
You'll have choose between 2 implementation routes:
Using a soft processor (NIOS II)
Writing the game logic in a hardware description language ([System]Verilog or VHDL)
The former will likely be the fastest route to achieving the completed game assuming you have some software background already, however if your intention is to learn to use FPGAs then option 2 may be more beneficial. If you use a NIOS or other soft processor core you'll still need to create an FPGA image and interface to external peripherals.
To get started you'll want to look at some of the example designs that come with your board. You also need to fully understand the underlying physical interface to the LED Matrix display to determine how to drive it. You then want to start partitioning your design into sensible blocks - a block to drive the display, a block to handle user input, storage of state, the game logic itself etc. Try and break them down sufficiently to decide what the interfaces to communicate between the blocks are going to look like.
In terms of implementation, for option 1 you will probably make use of Altera's SoC development environment called Qsys. Again working from an existing example design as a starting point is probably the easiest way to get up-and-running quickly. With option 2 you need to pick a hardware description language ([System]Verilog or VHDL or MyHDL) and code away in your favourite editor.
When you start writing RTL code you'll need a mechanism to simulate it. I'd suggest writing block-level simulations for each of the blocks you write (ideally writing the tests based on your definitions of the interfaces before writing the RTL). Assuming you're on a budget you don't have many options: Altera bundles a free version of Modelsim with their Quartus tool, there's the open source options of the Icarus simulator if using verilog or GHDL for VHDL.
When each block largely works run it through the synthesis tool to check FPGA resource utilisation and timing closure (the maximum frequency the design can be clocked at). You probably don't care too much about the frequency implementing a game like snake but it's still good practice to be aware of how what you write translates into an FPGA implementation and the impact on timing.
You'll need to create a Quartus project to generate an FPGA bitfile - again working from an existing example design is the way to go. This will provide pin locations and clock input frequencies etc. You may need to write timing constraints to define the timing to your LED Matrix display depending on the interface.
Then all you have to do is figure out why it works in simulation but not on the FPGA ;)
Let's say you have a LED matrix like this:
To answer not your question, but your comment about " if u can at least show me how to make the blinking LED i will be grateful :)", we can do as this:
module blink (input wire clk, /* assuming a 50MHz clock in your trainer */
output wire anode, /* to be connected to RC7 */
output wire cathode); /* to be connected to RB7 */
reg [24:0] freqdiv = 25'h0000000;
always #(posedge clk)
freqdiv <= freqdiv + 1;
assign cathode = 1'b0;
assign anode = freqdiv[24];
endmodule
This will make the top left LED to blink at a rate of 1,4 blinks per second aproximately.
This other example will show a running dot across the matrix, left to right, top to down:
module runningdot (input wire clk, /* assuming a 50MHz clock in your trainer */
output wire [7:0] anodes, /* to be connected to RC0-7 */
output wire [7:0] cathodes); /* to be connected to RB0-7 */
reg [23:0] freqdiv = 24'h0000000;
always #(posedge clk)
freqdiv <= freqdiv + 1;
wire clkled = freqdiv[23];
reg [7:0] r_anodes = 8'b10000000;
reg [7:0] r_cathodes = 8'b01111111;
assign anodes = r_anodes;
assign cathodes = r_cathodes;
always #(posedge clkled) begin
r_anodes <= {r_anodes[0], r_anodes[7:1]}; /* shifts LED left to right */
if (r_anodes == 8'b00000001) /* when the last LED in a row is selected... */
r_cathodes <= {r_cathodes[0], r_cathodes[7:1]}; /* ...go to the next row */
end
endmodule
Your snake game, if using logic and not an embedded processor, is way much complicated than these examples, but it will use the same logic principles to drive the matrix.

How do I get rid of sensitivity list warning when synthesizing Verilog code?

I am getting the warning that:
One or more signals are missing in the
sensitivity list of always block.
always#(Address)begin
ReadData = instructMem[Address];
end
How do I get rid of this warning?
Verilog does not require signal names in the sensitivity list. Use the #* syntax to signify that the always block should be triggered whenever any of its input signals change:
always #* begin
ReadData = instructMem[Address];
end
Add InstructMem to the sensitivity list.
Declare ReadData as a wire instead of a reg and then replace your always block with an assign.
assign ReadData = instructMem[Address];
I am not sure what the declaration of instructMem looks like. Anyway, ReadData = instructMem[address] is going to result in a multiplexer with address being treated as selection logic and instructMem as data lines of the multiplexer using a typical synthesis tool. You would need to put in instructMem in the sensitivity list since whenever this changes so should ReadData.
I tried Icarus, and you anyway cannot do something like always #(instructMem or address) where instructMem has a declaration like reg [7:0] instructMem [255:0] --> implying memory.
Note: do not try to synthesize Verilog memories this way, typically you are supposed to instantiate memory IPs and connect to their ports. Vendors provide memory models for such purposes.

Resources