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.
Related
I’m developing a boolean data logger on a ZYNQ 7000 SoC. The logger takes a boolean input from GPIO and logs the input’s value and the time it takes to flip.
I use a 32-bit register as a log entry, the MSB bit is the boolean value. The 30:0 bits is an unsigned integer which records the time between last 2 flips. The logger should work like the following picture.
Here's my implementation of the logger in Verilog. To read the logged data from the processor, I use an AXI slave interface generated by vivado and inline my logger in the AXI module.
module BoolLogger_AXI #(
parameter BufferDepth = 512
)(
input wire data_in, // boolean input
input wire S_AXI_ACLK, // clock
input wire S_AXI_ARESETN, // reset_n
// other AXI signals
);
wire slv_reg_wren; // write enable of AXI interface
reg[31:0] buff[0:BufferDepth-1];
reg[15:0] idx;
reg[31:0] count;
reg last_data;
always #(posedge S_AXI_ACLK) begin
if((!S_AXI_ARESETN) || slv_reg_wren) begin
idx <= 0;
count <= 1;
last_data <= data_in;
end else begin
if(last_data!=data_in) begin // add an entry only when input flips
last_data <= data_in;
if(idx < BufferDepth) begin // stop logging if buffer is full
buff[idx] <= count | (data_in << 31);
idx <= idx + 1;
end
count <= 1;
end else begin
count <= count + 1;
end
end
end
//other AXI stuff
endmodule
In the AXI module, the 512*32bit logged data is mapped to addresses from 0x43c20000 to 0x43c20800.
In the Verilog code, the logger adds a new entry only when the boolean input flips. In simulation, the module works as expected. But in the FPGA, sometimes the logged data is not valid. There are successive 2 data and their MSB bit is the same, which means the entry is added even when the boolean input stays the same.
The invalid data appear from time to time. I've tried reading from the address programmatically (*(u32*)(0x43c20000+4*idx)), and there are still invalid data. I watch idx in a ILA module and idx is 512, which means the logging finishes when I read the data.
The FPGA clock is 10 MHz. The input signal is 10 Hz. So the typical period is 10e6/10/2=0x7A120, which most of the data is close to, except the invalid data.
I think if the Verilog code is implemented well, there should be no such invalid data. What may be the problem? Is this an issue about timing?
The code
First off, are you absolutely sure you are not issuing an accidental write on the AXI bus, resetting the registers?
If so, have you tried inserting a so-called double-flop on data_in (two flip-flops, delaying the signal two clock ticks)? I suppose that your data_in is not synchronous to the FPGA clock, which will lead to metastability and you having bad days if not accounted for. Have a look here for information by NANDLAND.
Citing the linked source:
If you have ever tried to sample some input to your FPGA, such as a button press, or if you have had to cross clock domains, you have had to deal with Metastability. A metastable state is one in which the output of a Flip-Flop inside of your FPGA is unknown, or non-deterministic. When a metastable condition occurs, there is no way to tell if the output of your Flip-Flop is going to be a 1 or a 0. A metastable condition occurs when setup or hold times are violated.
Metastability is bad. It can cause your FPGA to exhibit very strange behavior.
In that source there is also a link to a white paper from Altera about the topic of metastability, linked here for reference.
Citing from that paper:
When a metastable signal does not resolve in the allotted time, a logic failure can result if the destination logic observes inconsistent logic states, that is, different destination registers capture different values for the metastable signal.
and
To minimize the failures due to metastability in asynchronous signal transfers, circuit designers typically use a sequence of registers (a synchronization register chain or synchronizer) in the destination clock domain to resynchronize the signal to the new clock domain. These registers allow additional time for a potentially metastable signal to resolve to a known value before the signal is used in the rest of the design.
Basically having the asynchronous signal routed to two flip-flops might for example lead to one FF reading a 1 and one FF reading a 0. This in turn could lead to the data point being saved, but the counter not being reset to 0 (hence doubling the measured time) and the bit being saved as 0.
Finally, it seems to me, that you are using the Vivado-generated example AXI core. Dan Gisselquist simply calls it "broken". This might not be the problem here, but you might want to have a look at his posts and his AXI core design.
I am able to use these default modules in xilinx schematic like M2_1 MUX, FD flipflop etc.
In verilog I can able to use only elementary gates like and, or ,not,xor etc.
But can I use these built-in Multiplexer (M2_1) or Flipflop(FD) in verilog?, because if I use behavioral code, there may be poor synthesis in synopsis or xilinx for some cases. Also I want to use system level design.
Please help me to solve this issue. Do I need to include any library to access this(built-in gates)?
Please provide me example codes. I want direct instantiation of these(Mux and Flipflop) in verilog just as and, or etc.
Yes you can use them in verilog. Xilinx provides user guides for how to do it (example for 7 series here)
The user guide that I've given link to provides an example for FDCE flip flop such as (page 131):
// FDCE:Single Data Rate D Flip-Flop with Asynchronous Clear and
// Clock Enable (posedge clk).
// 7 Series
// Xilinx HDL Libraries Guide, version 2012.2
FDCE #(
.INIT(1'b0)
// Initial value of register (1'b0 or 1'b1)
)
FDCE_inst
(
.Q(Q),
// 1-bit Data output
.C(C),
// 1-bit Clock input
.CE(CE),
// 1-bit Clock enable input
.CLR(CLR),
// 1-bit Asynchronous clear input
.D(D)
// 1-bit Data input
);
// End of FDCE_inst instantiation
The stick has a 12MHz oscillator on board. http://www.latticesemi.com/icestick
I have managed to write verilog code to divide this clock down and flash LEDs are 1Hz. (I am just starting to learn verilog.)
I believe that this FPGA will work at up to 133MHz.
Is there a way to generate a faster clock signal (in verilog) from the 12MHz oscillator?
Answer not yet tested.
Via https://www.reddit.com/r/yosys/comments/3yrq6d/are_plls_supported_on_the_icestick_hw/
From: https://github.com/SubProto/icestick-vga-test/blob/master/vga.v
wire clk;
SB_PLL40_CORE #(.FEEDBACK_PATH("SIMPLE"),
.PLLOUT_SELECT("GENCLK"),
.DIVR(4'b0001),
.DIVF(7'b1000010),
.DIVQ(3'b100),
.FILTER_RANGE(3'b001),
) uut (
.REFERENCECLK(pclk),
.PLLOUTCORE(clk),
.LOCK(D5),
.RESETB(1'b1),
.BYPASS(1'b0)
);
Also:
iCE40 sysCLOCK PLL
The iCE40 Phase Locked Loop (PLL) provides a variety of user-synthesizable clock frequencies, along with cus-
tom phase delays.The PLL in the iCE40 device can be configured and utilized with the help of software macros or
the PLL Module Generator. The PLL Module Generator utility helps users to quickly configure the desired settings
with the help of a GUI and generate Verilog code which configures the PLL macros. Figure 2 shows the iCE40 sys-
CLOCK PLL block diagram.
http://www.latticesemi.com/~/media/LatticeSemi/Documents/ApplicationNotes/IK/iCE40sysCLOCKPLLDesignandUsageGuide.pdf?document_id=47778
I have used a higher clock frequency to display a pong game in a VGA monitor using TinyFPGA BX. The TinyFPGA BX and the Lattice iCEstick are quite similar. Therefore, I would like to share my code. You may need to use the official Lattice software for an easier GUI (Graphical User Interface) configuration. https://www.latticesemi.com/software
module top(
input wire clk_16,
output USBPU
);
assign USBPU = 0; // drive USB pull-up resistor to '0' to disable USB
output wire;
SB_PLL40_CORE #(
.FEEDBACK_PATH("SIMPLE"),
.DIVR(4'b0000), // DIVR = 0
.DIVF(7'b0110001), // DIVF = 49
.DIVQ(3'b101), // DIVQ = 5
.FILTER_RANGE(3'b001) // FILTER_RANGE = 1
) uut (
.LOCK(locked),
.RESETB(1'b1),
.BYPASS(1'b0),
.REFERENCECLK(clk_16), // clk_16_MHz is the original clock
.PLLOUTCORE(clk) // clk is the modified clock with higher frequency
);
I found the following piece of code in the internet , while searching for good FIFO design. From the linkSVN Code FIFO -Author Clifford E. Cummings . I did some research , I was not able to figure out why there are three pointers in the design ?I can read the code but what am I missing ?
module sync_r2w #(parameter ADDRSIZE = 4)
(output reg [ADDRSIZE:0] wq2_rptr,
input [ADDRSIZE:0] rptr,
input wclk, wrst_n);
reg [ADDRSIZE:0] wq1_rptr;
always #(posedge wclk or negedge wrst_n)
if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;
else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
endmodule
module sync_w2r #(parameter ADDRSIZE = 4)
(output reg [ADDRSIZE:0] rq2_wptr,
input [ADDRSIZE:0] wptr,
input rclk, rrst_n);
reg [ADDRSIZE:0] rq1_wptr;
always #(posedge rclk or negedge rrst_n)
if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;
else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
endmodule
What you are looking at here is what's called a dual rank synchronizer. As you mentioned this is an asynchronous FIFO. This means that the read and write sides of the FIFO are not on the same clock domain.
As you know flip-flops need to have setup and hold timing requirements met in order to function properly. When you drive a signal from one clock domain to the other there is no way to guarantee this requirements in the general case.
When you violate these requirements FFs go into what is called a 'meta-stable' state where there are indeterminate for a small time and then (more or less) randomly go to 1 or 0. They do this though (and this is important) in much less than one clock cycle.
That's why the two layers of flops here. The first has a chance of going meta-stable but should resolve in time to be captured cleanly by the 2nd set of flops.
This on it's own is not enough to pass a multi-bit value (the address pointer) across clock domains. If more than one bit is changing at the same time then you can't be sure that the transition will be clean on the other side. So what you'll see often in these situations is that the FIFO pointers will by gray coded. This means that each increment of the counter changes at most one bit at a time.
e.g. Rather than 00 -> 01 -> 10 -> 11 -> 00 ... it will be 00 -> 01 -> 11 -> 10 -> 00 ...
Clock domain crossing is a deep and subtle subject. Even experienced designers very often mess them up without careful thought.
BTW ordinary Verilog simulations will not show anything about what I just described in a zero-delay sim. You need to do back annotated SDF simulations with real timing models.
In this example, the address is passed through the shift register in order for it to be delayed by one clock cycle. There could have been more “pointers” in order to delay the output even more.
Generally, it is easier to understand what is going on and why if you simulate the design and look at the waveform.
Also, here are some good FIFO implementations you can look at:
Xilinx FIFO Generator IP Core
Altera's single/double-clock FIFOs
OpenCores Generic FIFOs
Hope it helps. Good Luck!
I have a clock input to the fan-out buffer which drives LVDS input to the bottom edge of PLL input. There are two pins - AJ19 (active high) and a complementary AK19 pin (active low). I am only interested in AJ19, so my top level module looks like this:
module top(clk, ...);
...
endmodule
Here is my pinout for a clk:
set_instance_assignment -name IO_STANDARD LVDS -to clk
set_location_assignment PIN_AJ19 -to clk
set_location_assignment PIN_AK19 -to "clk(n)"
So far so good, but fitter is generating a very annoying warning that drives me crazy:
Warning (15714): Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details
Warning (176674): Following 1 pins are differential I/O pins but do not have their complement pins. Hence, the Fitter automatically created the complement pins.
Warning (176118): Pin "clk" is a differential I/O pin but does not have its complement pin. Hence, fitter automatically created the complement pin "clk(n)"
Altera's knowledge base suggested to actually define the clock as a pair (i.e. input wire [1:0] clk) to remove the warning. That doesn't quite help because then you get another warning, saying that input pin does not drive any logic.
I have tried to disable this warning using // altera message_off 176118. That results in error because "176118" is not a valid message ID.
Any suggestions on how to solve this problem?
See Altera "Designing with Low-Level Primitives User Guide" for primitive details and templates
http://www.altera.co.uk/literature/ug/ug_low_level.pdf
Example of wrapping top level block:
module top_wrap (
...
input wire refclk, input wire refclk_n,
);
// differential input buffers
wire int_refclk;
ALT_INBUF_DIFF inbuf_refclk (
.i (refclk),
.ibar (refclk_n),
.o(int_refclk),
);
top wrapped (
.refclk( int_refclk),
...
)
endmodule
To get rid of this, you need to create both signals, and then take them into an LVDS buffer component (I don't recall what Altera calls this component off the top of my head), the output of which will drive a "normal" internal signal that you can then use as you see fit.