My verilog VGA driver causes the screen to flicker (Basys2) - verilog
I'm trying to recreate Adventure(1979) in Verilog and so far I have character movement, collision and map generation done. It didn't flicker that much before I separated the maps into modules now it flickers constantly. When I was looking up this issue, I found out that the clock on the Basys2 board is pretty noisy and could be the culprit. However, putting the maps into modules shouldn't have made it worse unless I messed something up. Any idea what happened?
Here's my map generator:
module map_generator(clk_vga, reset, CurrentX, CurrentY, HBlank, VBlank, playerPosX, playerPosY, mapData
);
input clk_vga;
input reset;
input [9:0]CurrentX;
input [8:0]CurrentY;
input HBlank;
input VBlank;
input [9:0]playerPosX;
input [8:0]playerPosY;
output [7:0]mapData;
reg [7:0]mColor;
reg [5:0]currentMap = 0;
wire [7:0]startCastle;
StartCastle StartCastle(
.clk_vga(clk_vga),
.CurrentX(CurrentX),
.CurrentY(CurrentY),
.mapData(startCastle)
);
always #(posedge clk_vga) begin
if(reset)begin
currentMap <= 0;
end
end
always #(posedge clk_vga) begin
if(HBlank || VBlank) begin
mColor <= 0;
end
else begin
if(currentMap == 4'b0000) begin
mColor[7:0] <= startCastle[7:0];
end
//Add more maps later
end
end
assign mapData[7:0] = mColor[7:0];
endmodule
Here's the startCastle:
module StartCastle(clk_vga, CurrentX, CurrentY, active, mapData);
input clk_vga;
input [9:0]CurrentX;
input [8:0]CurrentY;
input active;
output [7:0]mapData;
reg [7:0]mColor;
always #(posedge clk_vga) begin
if(CurrentY < 40) begin
mColor[7:0] <= 8'b11100000;
end
else if(CurrentX < 40) begin
mColor[7:0] <= 8'b11100000;
end
else if(~(CurrentX < 600)) begin
mColor[7:0] <= 8'b11100000;
end
else if((~(CurrentY < 440) && (CurrentX < 260)) || (~(CurrentY < 440) && ~(CurrentX < 380))) begin
mColor[7:0] <= 8'b11100000;
end else
mColor[7:0] <= 8'b00011100;
end
assign mapData = mColor;
endmodule
Here's the VGA driver which is connected to my top module:
module vga_driver(clk_50MHz, vs_vga, hs_vga, RED, GREEN, BLUE, HBLANK, VBLANK, CURX, CURY, COLOR, CLK_DATA, RESET);
input clk_50MHz;
output vs_vga;
output hs_vga;
output [2:0] RED;
output [2:0] GREEN;
output [1:0] BLUE;
output HBLANK;
output VBLANK;
reg VS = 0;
reg HS = 0;
input RESET;
//current client data
input [7:0] COLOR;
output CLK_DATA;
output [9:0] CURX;
output [8:0] CURY;
//##### Module constants (http://tinyvga.com/vga-timing/640x480#60Hz)
parameter HDisplayArea = 640; // horizontal display area
parameter HLimit = 800; // maximum horizontal amount (limit)
parameter HFrontPorch = 16; // h. front porch
parameter HBackPorch = 48; // h. back porch
parameter HSyncWidth = 96; // h. pulse width
parameter VDisplayArea = 480; // vertical display area
parameter VLimit = 525; // maximum vertical amount (limit)
parameter VFrontPorch = 10; // v. front porch
parameter VBackPorch = 33; // v. back porch
parameter VSyncWidth = 2; // v. pulse width
//##### Local variables
wire clk_25MHz;
reg [9:0] CurHPos = 0; //maximum of HLimit (2^10 - 1 = 1023)
reg [9:0] CurVPos = 0; //maximum of VLimit
reg HBlank_reg, VBlank_reg, Blank = 0;
reg [9:0] CurrentX = 0; //maximum of HDisplayArea
reg [8:0] CurrentY = 0; //maximum of VDisplayArea (2^9 - 1 = 511)
//##### Submodule declaration
clock_divider clk_div(.clk_in(clk_50MHz), .clk_out(clk_25MHz));
//shifts the clock by half a period (negates it)
//see timing diagrams for a better understanding of the reason for this
clock_shift clk_shift(.clk_in(clk_25MHz), .clk_out(CLK_DATA));
//simulate the vertical and horizontal positions
always #(posedge clk_25MHz) begin
if(CurHPos < HLimit-1) begin
CurHPos <= CurHPos + 1;
end
else begin
CurHPos <= 0;
if(CurVPos < VLimit-1)
CurVPos <= CurVPos + 1;
else
CurVPos <= 0;
end
if(RESET) begin
CurHPos <= 0;
CurVPos <= 0;
end
end
//##### VGA Logic (http://tinyvga.com/vga-timing/640x480#60Hz)
//HSync logic
always #(posedge clk_25MHz)
if((CurHPos < HSyncWidth) && ~RESET)
HS <= 1;
else
HS <= 0;
//VSync logic
always #(posedge clk_25MHz)
if((CurVPos < VSyncWidth) && ~RESET)
VS <= 1;
else
VS <= 0;
//Horizontal logic
always #(posedge clk_25MHz)
if((CurHPos >= HSyncWidth + HFrontPorch) && (CurHPos < HSyncWidth + HFrontPorch + HDisplayArea) || RESET)
HBlank_reg <= 0;
else
HBlank_reg <= 1;
//Vertical logic
always #(posedge clk_25MHz)
if((CurVPos >= VSyncWidth + VFrontPorch) && (CurVPos < VSyncWidth + VFrontPorch + VDisplayArea) || RESET)
VBlank_reg <= 0;
else
VBlank_reg <= 1;
//Do not output any color information when we are in the vertical
//or horizontal blanking areas. Set a boolean to keep track of this.
always #(posedge clk_25MHz)
if((HBlank_reg || VBlank_reg) && ~RESET)
Blank <= 1;
else
Blank <= 0;
//Keep track of the current "real" X position. This is the actual current X
//pixel location abstracted away from all the timing details
always #(posedge clk_25MHz)
if(HBlank_reg && ~RESET)
CurrentX <= 0;
else
CurrentX <= CurHPos - HSyncWidth - HFrontPorch;
//Keep track of the current "real" Y position. This is the actual current Y
//pixel location abstracted away from all the timing details
always #(posedge clk_25MHz)
if(VBlank_reg && ~RESET)
CurrentY <= 0;
else
CurrentY <= CurVPos - VSyncWidth - VFrontPorch;
assign CURX = CurrentX;
assign CURY = CurrentY;
assign VBLANK = VBlank_reg;
assign HBLANK = HBlank_reg;
assign hs_vga = HS;
assign vs_vga = VS;
//Respects VGA Blanking areas
assign RED = (Blank) ? 3'b000 : COLOR[7:5];
assign GREEN = (Blank) ? 3'b000 : COLOR[4:2];
assign BLUE = (Blank) ? 2'b00 : COLOR[1:0];
endmodule
clk_div:
module clock_divider(clk_in, clk_out);
input clk_in;
output clk_out;
reg clk_out = 0;
always #(posedge clk_in)
clk_out <= ~clk_out;
endmodule
clk_shift:
module clock_shift(clk_in, clk_out);
input clk_in;
output clk_out;
assign clk_out = ~clk_in;
endmodule
I'm posting this as an answer because I cannot put a photo in a comment.
Is this what your design looks like?
My only guess ATM is that you might have misplaced some ports during instantiation of vga_driver and/or map_generator (if you used the old style instantiation). Nevertheless, I'm going to check VGA timmings, as I can see a strange vertical line at the left of the screen, as if the hblank interval was visible.
By the way: I've changed the way you generate the display. You use regs for HS, VS, etc, which get updated the next clock cycle. I treat display generation as a FSM, so outputs come from combinational blocks triggered by certain values (or range of values) from the counters. Besides, I start horizontal and vertical counters so position (0,0) measured in pixel coordinates in the screen actually maps to values (0,0) from horizontal and vertical counters, so no arithmetic needed.
This is my version of VGA display generation:
module videosyncs (
input wire clk,
input wire [2:0] rin,
input wire [2:0] gin,
input wire [1:0] bin,
output reg [2:0] rout,
output reg [2:0] gout,
output reg [1:0] bout,
output reg hs,
output reg vs,
output wire [10:0] hc,
output wire [10:0] vc
);
/* http://www.abramovbenjamin.net/calc.html */
// VGA 640x480#60Hz,25MHz
parameter htotal = 800;
parameter vtotal = 524;
parameter hactive = 640;
parameter vactive = 480;
parameter hfrontporch = 16;
parameter hsyncpulse = 96;
parameter vfrontporch = 11;
parameter vsyncpulse = 2;
parameter hsyncpolarity = 0;
parameter vsyncpolarity = 0;
reg [10:0] hcont = 0;
reg [10:0] vcont = 0;
reg active_area;
assign hc = hcont;
assign vc = vcont;
always #(posedge clk) begin
if (hcont == htotal-1) begin
hcont <= 0;
if (vcont == vtotal-1) begin
vcont <= 0;
end
else begin
vcont <= vcont + 1;
end
end
else begin
hcont <= hcont + 1;
end
end
always #* begin
if (hcont>=0 && hcont<hactive && vcont>=0 && vcont<vactive)
active_area = 1'b1;
else
active_area = 1'b0;
if (hcont>=(hactive+hfrontporch) && hcont<(hactive+hfrontporch+hsyncpulse))
hs = hsyncpolarity;
else
hs = ~hsyncpolarity;
if (vcont>=(vactive+vfrontporch) && vcont<(vactive+vfrontporch+vsyncpulse))
vs = vsyncpolarity;
else
vs = ~vsyncpolarity;
end
always #* begin
if (active_area) begin
gout = gin;
rout = rin;
bout = bin;
end
else begin
gout = 3'h00;
rout = 3'h00;
bout = 2'h00;
end
end
endmodule
Which is instantiated by your vga_driver module, which becomes nothing but a wrapper for this module:
module vga_driver (
input wire clk_25MHz,
output wire vs_vga,
output wire hs_vga,
output wire [2:0] RED,
output wire [2:0] GREEN,
output wire [1:0] BLUE,
output wire HBLANK,
output wire VBLANK,
output [9:0] CURX,
output [8:0] CURY,
input [7:0] COLOR,
input wire RESET
);
assign HBLANK = 0;
assign VBLANK = 0;
videosyncs syncgen (
.clk(clk_25MHz),
.rin(COLOR[7:5]),
.gin(COLOR[4:2]),
.bin(COLOR[1:0]),
.rout(RED),
.gout(GREEN),
.bout(BLUE),
.hs(hs_vga),
.vs(vs_vga),
.hc(CURX),
.vc(CURY)
);
endmodule
Note that in map_generator, the first if statement in this always block will never be true. We can forget about it, as the VGA display module will blank RGB outputs when needed.
always #(posedge clk_vga) begin
if(HBlank || VBlank) begin //
mColor <= 0; // Never reached
end //
else begin //
if(currentMap == 4'b0000) begin
mColor[7:0] <= startCastle[7:0];
end
//Add more maps later
end
end
Using the same approach, I've converted the map generator module to be a combinational module. For example, for map 0 (the castle -without the castle, I see-) it is like this:
module StartCastle(
input wire [9:0] CurrentX,
input wire [8:0] CurrentY,
output wire [7:0] mapData
);
reg [7:0] mColor;
assign mapData = mColor;
always #* begin
if(CurrentY < 40) begin
mColor[7:0] <= 8'b11100000;
end
else if(CurrentX < 40) begin
mColor[7:0] <= 8'b11100000;
end
else if(~(CurrentX < 600)) begin
mColor[7:0] <= 8'b11100000;
end
else if((~(CurrentY < 440) && (CurrentX < 260)) || (~(CurrentY < 440) && ~(CurrentX < 380))) begin
mColor[7:0] <= 8'b11100000;
end else
mColor[7:0] <= 8'b00011100;
end
endmodule
Just a FSM whose output is the colour that goes in a pixel. The input being the coordinates of the current pixel.
So when it is time to display map 0, map_generator simply switches to it based upon the current value of currentMap
module map_generator (
input wire clk,
input wire reset,
input wire [9:0]CurrentX,
input wire [8:0]CurrentY,
input wire HBlank,
input wire VBlank,
input wire [9:0]playerPosX,
input wire [8:0]playerPosY,
output wire [7:0]mapData
);
reg [7:0] mColor;
assign mapData = mColor;
reg [5:0]currentMap = 0;
wire [7:0] castle_map;
StartCastle StartCastle(
.CurrentX(CurrentX),
.CurrentY(CurrentY),
.mapData(castle_map)
);
always #(posedge clk) begin
if(reset) begin
currentMap <= 0;
end
end
always #* begin
if(currentMap == 6'b000000) begin
mColor = castle_map;
end
//Add more maps later
end
endmodule
This may look like a lot of comb logic is generated and so glitches may happen. It's actually very fast, no noticeable glitches on screen, and you can use the actual current x and y coordinates to choose what to display on screen. Thus, no need for an inverted clock. My final version of your design has only one 25MHz clock.
By the way, you want to keep device dependent constructions away from your design, placing things like clock generators in separate modules that will be connected to your design in the top module, which should be the only device dependent module.
So, I've written a device-agnostic adventure module, which will contain the entire game:
module adventure (
input clk_vga,
input reset,
output vs_vga,
output hs_vga,
output [2:0] RED,
output [2:0] GREEN,
output [1:0] BLUE
);
wire HBLANK, VBLANK;
wire [7:0] COLOR;
wire [9:0] CURX;
wire [8:0] CURY;
wire [9:0] playerPosX = 10'd320; // no actually used in the design yet
wire [8:0] playerPosY = 9'd240; // no actually used in the design yet
vga_driver the_screen (.clk_25MHz(clk_vga),
.vs_vga(vs_vga),
.hs_vga(hs_vga),
.RED(RED),
.GREEN(GREEN),
.BLUE(BLUE),
.HBLANK(HBLANK),
.VBLANK(VBLANK),
.CURX(CURX),
.CURY(CURY),
.COLOR(COLOR)
);
map_generator the_mapper (.clk(clk_vga),
.reset(reset),
.CurrentX(CURX),
.CurrentY(CURY),
.HBlank(HBLANK),
.VBlank(VBLANK),
.playerPosX(playerPosX),
.playerPosY(playerPosY),
.mapData(COLOR)
);
endmodule
This module is not complete: it lacks inputs from joystick or any other input device to update player current position. For now, player current position is fixed.
The top level design (TLD) is written exclusively for the FPGA trainer you have. It is here where you need to generate proper clocks using your device's available resources, such as the DCM in Spartan 3/3E devices.
module tld_basys(
input wire clk_50MHz,
input wire RESET,
output wire vs_vga,
output wire hs_vga,
output wire [2:0] RED,
output wire [2:0] GREEN,
output wire [1:0] BLUE
);
wire clk_25MHz;
dcm_clocks gen_vga_clock (
.CLKIN_IN(clk_50MHz),
.CLKDV_OUT(clk_25MHz)
);
adventure the_game (.clk_vga(clk_25MHz),
.reset(RESET),
.vs_vga(vs_vga),
.hs_vga(hs_vga),
.RED(RED),
.GREEN(GREEN),
.BLUE(BLUE)
);
endmodule
The DCM generated clocks goes in this module (generated by the Xilinx Core Generator)
module dcm_clocks (CLKIN_IN,
CLKDV_OUT
);
input CLKIN_IN;
output CLKDV_OUT;
wire CLKFB_IN;
wire CLKFX_BUF;
wire CLKDV_BUF;
wire CLKIN_IBUFG;
wire CLK0_BUF;
wire GND_BIT;
assign GND_BIT = 0;
BUFG CLKDV_BUFG_INST (.I(CLKDV_BUF),
.O(CLKDV_OUT));
IBUFG CLKIN_IBUFG_INST (.I(CLKIN_IN),
.O(CLKIN_IBUFG));
BUFG CLK0_BUFG_INST (.I(CLK0_BUF),
.O(CLKFB_IN));
DCM_SP #(.CLKDV_DIVIDE(2.0), .CLKIN_DIVIDE_BY_2("FALSE"),
.CLKIN_PERIOD(20.000), .CLKOUT_PHASE_SHIFT("NONE"),
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"), .DFS_FREQUENCY_MODE("LOW"),
.DLL_FREQUENCY_MODE("LOW"), .DUTY_CYCLE_CORRECTION("TRUE"),
.FACTORY_JF(16'hC080), .PHASE_SHIFT(0), .STARTUP_WAIT("FALSE") )
DCM_SP_INST (.CLKFB(CLKFB_IN),
.CLKIN(CLKIN_IBUFG),
.DSSEN(GND_BIT),
.PSCLK(GND_BIT),
.PSEN(GND_BIT),
.PSINCDEC(GND_BIT),
.RST(GND_BIT),
.CLKDV(CLKDV_BUF),
.CLKFX(),
.CLKFX180(),
.CLK0(CLK0_BUF),
.CLK2X(),
.CLK2X180(),
.CLK90(),
.CLK180(),
.CLK270(),
.LOCKED(),
.PSDONE(),
.STATUS());
endmodule
Although it is safe (for Xilinx devices) to use a simple clock divider as you did. If you fear that the synthesizer won't treat your divided clock as an actual clock, add a BUFG primitive to route the output from the divider to a global buffer so it can be used as a clock with no problems (see the module above for an example on how to do this).
As a final note, you may want to add more independency from the final device, by using 24-bit colours for your graphics. At the TLD, you will use the actual number of bits per colour component you really have, but if you move from the Basys2 with 8-bit colour trainer board to the, say, Nexys4 board, with 12-bit colour, you will automatically enjoy a richer output display.
Now, it looks like this (no vertical bars at the left, and colours seem to be more vibrant)
Related
ModelSim simulation works but FPGA fails. What am I missing?
Sorry if anything in here seems obvious but I am starting out in this new FPGA thing and I really enjoy it so far but this is driving me crazy. Here is the Verilog code for a block that should in principle do the following to an 8 bit register: 00000001 00000010 00000100 ..... 01000000 10000000 01000000 00100000 module bit_bouncer(clock, enable, bouncer_out); //INPUTS PORTS input clock; input enable; //OUTPUTS PORTS output bouncer_out; //INPUT DATA TYPE wire clock; wire enable; //OUTPUT DATA TYPE reg [7:0] bouncer_out = 8'b00000001; //Register to store data reg direction = 0; //CODE STARTS HERE always # (posedge clock) begin if(enable) begin bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1); direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction; end end endmodule This works perfectly in simulation but fails on the FPGA (DE10-Nano board, if interested). I should also point out that this gets driven by a clock passed trough a PLL on the FPGA that is then passed trough a divideByN block. Here is the code for the divideByN block: module clk_divn #( parameter WIDTH = 20, parameter N = 1000000) (clk,reset, clk_out); input clk; input reset; output clk_out; reg [WIDTH-1:0] pos_count = {WIDTH{1'b0}}; reg [WIDTH-1:0] neg_count = {WIDTH{1'b0}}; wire [WIDTH-1:0] r_nxt = {WIDTH{1'b0}}; always #(posedge clk) if (reset) pos_count <=0; else if (pos_count ==N-1) pos_count <= 0; else pos_count<= pos_count +1; always #(negedge clk) if (reset) neg_count <=0; else if (neg_count ==N-1) neg_count <= 0; else neg_count<= neg_count +1; assign clk_out = ((pos_count > (N>>1)) | (neg_count > (N>>1))); endmodule The divideByN has also been tested in simulation and works fine. I actually made a simulation in which the divideByN is connected to the "bouncer_block" if I can call it like that and it also works. Everything simulates but nothing works in real life....but isn't it always like that :P I hope someone can help me figure this out because I really want to learn more about FPGA and use them in future projects. If you read all this you are awesome and I wish you an amazing day :)
Your bit bouncer is not operating synchronously to the system clock and neither does it have a reset condition, which is a recipe for trouble. A better approach is to use a clock strobe and test for it on edges of the main system clock. Also, all inputs from tactile buttons should be synchronised to the system clock and debounced. Something like this: Schematic RTL BitBouncer module BitBouncer ( input wire clock, input wire reset, input wire enable, input wire clock_strobe, output reg[7:0] bouncer_out ); // Register to store data reg direction = 0; // CODE STARTS HERE always #(posedge clock) begin if (reset) begin bouncer_out = 1; direction = 0; end else if (enable && clock_strobe) begin bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1); direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction; end end endmodule ClockStrobe module ClockStrobe #( parameter MAX_COUNT = 50000000 ) ( input wire clock, input wire reset, output reg clock_strobe ); reg [$clog2(MAX_COUNT) - 1: 0] counter; always #(posedge clock) begin if (reset) begin counter <= 0; end else begin counter <= counter + 1; if (counter == MAX_COUNT) begin clock_strobe <= 1; counter <= 0; end else begin clock_strobe <= 0; end end end endmodule Sync module Sync ( input wire clock, input wire in, output reg out ); reg [2:0] sync_buffer; initial begin out = 0; sync_buffer = 3'd0; end always #* begin out <= sync_buffer[2]; end always #(posedge clock) begin sync_buffer[0] <= in; sync_buffer[2:1] <= sync_buffer[1:0]; end endmodule Debounce module Debounce #( parameter MAX_COUNT = 2500000 ) ( input wire clock, input wire in, output reg out ); reg previous_in; reg [$clog2(MAX_COUNT) - 1:0] counter; initial begin previous_in = 0; counter = 0; out = 0; end always #(posedge clock) begin counter <= counter + 1; if (counter == MAX_COUNT) begin out <= previous_in; counter <= 0; end else if (in != previous_in) begin counter <= 0; end previous_in <= in; end endmodule
I have tried to add a reset with no success but I have made my own divideByN and kept the reset Charles suggested and now it's working flawlessly. I think the code for the divideByN I took online might be unable to synthesize properly. Here is my new code for the divideByN: module my_div_n #(parameter N = 1_000_000, parameter WIDTH = 20) (clock_in, clock_out); input wire clock_in; output reg clock_out; reg[WIDTH-2:0] counter; //WIDTH-2 because the last bit is taken care of by the fact that we flip the output (it acts as the last bit) always # (posedge clock_in) begin counter <= counter + 19'b1; if(counter == N>>1) begin counter <= 0; clock_out <= !clock_out; end end endmodule And the code for my bit_bouncer: module bit_bouncer(clock, enable, reset, bouncer_out); //INPUTS PORTS input clock; input enable; input reset; //OUTPUTS PORTS output [7:0] bouncer_out; //INPUT DATA TYPE wire clock; wire enable; wire reset; //OUTPUT DATA TYPE reg [7:0] bouncer_out; //Register to store data reg direction; //CODE STARTS HERE always # (posedge clock) begin if(reset) begin bouncer_out <= 8'b00000001; direction <= 0; end else if(enable) begin bouncer_out = direction ? (bouncer_out >> 1) : (bouncer_out << 1); direction <= (bouncer_out == 8'b00000001 || bouncer_out == 8'b10000000) ? ~direction : direction; end end endmodule Here how everything is wired: I would still like to know the purpose of the clock strobe because you make it seem as if I should probably know this if I want to understand my circuit better and all about synchronicity.
Always loop that does not assign the outputs
I am making an average that resets every period on EDA Playground. No errors are displayed on the simulator, Icarus Verilog, but the outputs are continually unassigned (which, of course, is not what I intended). Here is my design: module shift ( input [13:0] in, input clock, output [31:0] sum, output [14:0] avg); integer reset; reg [31:0] sum_reg; reg [14:0] avg_reg; always #(posedge clock) if (reset == 8) begin avg_reg = sum_reg >> 3; sum_reg = 0; reset = 0; end else begin sum_reg = sum_reg + in; reset = reset + 1; end assign sum = sum_reg; assign avg = avg_reg; endmodule Here is my testbench: module shift_tb; reg [13:0] in; reg clock = 1'b0; reg reset; wire [31:0] sum; wire [14:0] avg; shift s ( .in(in), .clock(clock), .sum(sum), .avg(avg)); integer f; initial begin for (f = 9000; f < 10000; f = f + 10) begin in = f; $display("in = %d, sum = %d, avg = %d", in, sum, avg); end end always #1 clock = ~clock; endmodule What is wrong with this code?
One problem is reset is an integer that is initially x and stays that way. You need a way of initializing it to 0. Another problem is your testbench for-loop has no delay. You should add #(nedgedge clk)
How to connect my clockDivider into this verilog program with Quartus II
Code: TestBench.v: // ============================================================ // // Traffic light tester module. // // We clock the device as usual, supply reset, and eventually "push // the walk button" to activate the traffic light. // // ============================================================ // `timescale 1 ns / 1 ns module TestBench; reg clk; // Clock into the FPGA reg walk; // A button that causes the walk light to go on reg reset; // The reset line to your design wire green; // The green light on Dodge Street wire yellow; // The yellow light on ... wire red; // The red light on ... wire go; // The walk light for the pedestrian wire stop; // The "don't walk" light // Here is your FPGA chip Traffic yourChip( reset, clk, walk, green, yellow, red, go, stop ); // Provide clocking to the FPGA always begin #10 clk = ~clk; end // Start up code. initial begin clk = 0; walk = 0; reset = 1; #100 reset = 0; end // Eventually we want to "push the walk button" which causes the // traffic lights to cycle yellow, red, then back to green. // Also, we want to stop the sim at some point too. initial begin #1000 walk = 1; #100 walk = 0; #100000 $stop; end endmodule // QuasiTestBench clockDivder.v: module clockDivider( input wire clock, input wire reset, output wire dividedClk ); reg [127:0] counter; always #(posedge clock or posedge reset) begin if(reset == 1) counter <=0; else counter <= counter + 1; end assign dividedClk = counter[127]; endmodule Traffic.v: module Traffic( reset, clock, walk, green, yellow, red, walkLight, handLight); input wire reset; input wire clock; input wire walk; output reg green, yellow, red, walkLight, handLight; reg[2:0] state; reg[3:0] count; //we want some kind of state machine here. //let's define some states parameter s0 = 0 //green , s1=1 //yellow , s2=2; //red reg[3:0] timeButtonPushed; //clockDivider myClock(clock, reset); always #(posedge clock or posedge reset) begin if (reset == 1) begin state <= s0; //default to green light on reset. handLight = 1; green = 1; timeButtonPushed = 0; count <= 0; end else case(state) s0: begin if(walk == 1) begin //compute 10s timeout before switch to yellow //requires us to capture some info about time button pushed timeButtonPushed = count; //record time button was pushed end else if(timeButtonPushed == (count - 10)) begin state = s1; //We've reached countdown state set light to yellow. green = 0; yellow = 1; end count = count + 1; end s1: begin if(timeButtonPushed == (count - 15)) //We've reached timeout for yellow light. begin state = s2; //move to red state handLight = 0; walkLight = 1; red = 1; end count = count + 1; end s2: begin if(timeButtonPushed == count - 45) begin state = s0; //move back to green state red = 0; walkLight = 0; handLight = 1; green = 0; timeButtonPushed = 0; end count = count + 1; end default: state <= s0; endcase end endmodule I've tried to instantiate the clockDivider in the TestBench, and I've also tried to instantiate it in Traffic.v attempting to insert it in between the clock and the input clk wire in Traffic.v Ideally I'd like a solution that shows me the correct way to wire the clockDivider properly, however if there are other ways--even if hack-ish to get it done I'd appreciate it. I've also tried forgetting clockDivider.v entirely and replaced the clock code with this: reg [127:0] counter; always begin if(reset == 1) counter <=0; else if(counter == 126) assign clk = ~clk; else counter <= counter + 1; end But that too appears to fail.
Firstly, in your sample instantiation, you aren't connencting any signal to the dividedClk output. As such, it's hard to see what you're trying to use it for. You're allowed to omit connections, but you need the delimiting commas. Try: clockDivider myClock(clock, reset,); Secondly, generating a clock with logic is poor design - you'll have major issues with timing. Logic signals can't be properly loaded onto the clock tree network, so you can get a large clock skew as a result. Instead, use your counter as an enable signal to any "slower" registers and use the global clock, or make use of a PLL/DLL to generate a new (slower) clock signal. As an example of the first: reg enable; reg [127:0] counter; parameter NUMBEROFCYCLES = 100; always #(posedge clk) begin if (reset) enable <= 0; else if (counter == NUMBEROFCYCLES) enable <= 1; else enable <= 0; end always #(posedge clk) begin if (reset) counter <= 0; else if (counter == NUMBEROFCYCLES) counter <= 0; else counter <= counter + 1; end always #(posedge clk) begin if (reset) <<reset some signals>> else if (enable) <<change some signals>> else <<signals <= signals>> end
Query : No display on monitor ( VGA CONTROLLER 800*600 resolution ) BASYS 2 BOARD
I have created this code for vga controller and the simulation is proper too. The problem is the monitor is blank when code runs, also in the waveform generation the two output's hsync and vsync are displayed '0'. I have no idea where the logic goes wrong. Please help. Code : module anymodule(input wire clk,reset, output wire hsynch,vsynch, output [2:0] red, output [2:0] green, output [1:0] blue, output video_on); // defining constants localparam HD = 800; // horizontal display area localparam HF = 56; // front porch (right border) localparam HB = 64; //right porch (left border) localparam HR = 120; // horizontal retrace localparam VD = 600; // vertical display area localparam VF = 37; // front porch (bottom border) localparam VB = 23; // back porch (top border) localparam VR = 6; // vertical retrace //horizontal and vertical counter reg [9:0] h_count = 0; reg [9:0] v_count = 0; wire [9:0] h_end,v_end; assign h_end = HD+HF+HR+HB-1; assign v_end = VD+VF+VR+VB-1; always #(*) begin if(clk) if(h_end) h_count = 0; else h_count = h_count+1; else h_count = h_count; end always #(posedge clk) begin if(h_end) if(v_count<v_end) v_count = v_count+1; else v_count = 0; else v_count = v_count; end assign hsynch = ((h_count >= HD+HF-1) && (h_count <= HD+HF+HR+HB-1)); assign vsynch = ((v_count >= VD+VF-1) && (v_count <= VD+VF+VR+VB-1)); assign video_on = ((h_count < HD) && (v_count < VD)); wire [9:0] pixel_x,pixel_y; assign pixel_x = (video_on)? h_count : 10'b0; assign pixel_y = (video_on)? v_count : 10'b0; reg [7:0] coloroutput; always #(clk) if(~video_on) coloroutput <= 0; else begin if( pixel_x<150 && pixel_y<160) coloroutput[7:5] <= 3'b111; else if(pixel_x<250 && pixel_y<320) coloroutput[4:2] <= 3'b111; else coloroutput[1:0] <= 2'b11; end assign red = (video_on) ? coloroutput[7:5] : 3'b000; assign green = (video_on) ? coloroutput[4:2] : 3'b000; assign blue = (video_on) ? coloroutput[1:0] : 3'b000; endmodule
You should definitely try simulating this. I'm pretty sure you'll find that your code doesn't work in simulation. Always check your code in a simulation environment before trying to program your FPGA! You have this line: always #(*) begin if(clk) if(h_end) h_count = 0; h_end is a static value, you need to be comparing it to something. Maybe: if (h_count == h_end) something like that. Additionally, this always block should tell the tools to look for a rising edge on your clock signal. E.g. always #(posedge clk) begin if (h_count == h_end)
Query : Error in clock divider used in VGA Controller (Verilog) Basys 2 board
I am getting an error while incorporating clock divider ( 40 MHz ) in my VGA Controller (Basys 2 board ). Error in my coding is - Port I of input buffer instance_name/CLKIN_IBUFG_INST is connected to GND. Please help in removing this error ! Code is as follows : module anymodule(input wire clk,reset, output wire hsynch,vsynch, output [2:0] red, output [2:0] green, output [1:0] blue, output video_on); // defining constants localparam HD = 800; // horizontal display area localparam HF = 40; // front porch (right border) localparam HB = 88; //right porch (left border) localparam HR = 128; // horizontal retrace localparam VD = 600; // vertical display area localparam VF = 1; // front porch (bottom border) localparam VB = 23; // back porch (top border) localparam VR = 4; // vertical retrace wire pixel_tick; //clock divider // Instantiate the module clkdiv instance_name ( .CLKIN_IN(CLKIN_IN), .RST_IN(RST_IN), .CLKFX_OUT(pixel_tick), .CLKIN_IBUFG_OUT(CLKIN_IBUFG_OUT), .CLK0_OUT(CLK0_OUT), .LOCKED_OUT(LOCKED_OUT) ); //horizontal and vertical counter reg [9:0] h_count = 0; reg [9:0] v_count = 0; wire [9:0] h_end,v_end; assign h_end = HD+HF+HR+HB-1; assign v_end = VD+VF+VR+VB-1; always #(pixel_tick) if(h_count<h_end) h_count <= h_count+1; else h_count <= 0; always #(*) if(pixel_tick & h_end) if(v_count<v_end) v_count <= v_count+1; else v_count <= 0; else v_count <= v_count; assign hsynch = ((h_count>= HD+HF-1) && (h_count<=HD+HF+HR+HB-1)); assign vsynch = ((v_count>=VD+VF-1) && (v_count<= VD+VF+VR+VB-1)); assign video_on = ((h_count <HD) && (v_count<VD)); wire [9:0] pixel_x,pixel_y; assign pixel_x = (video_on)? h_count : 'b0; assign pixel_y = (video_on)? v_count : 'b0; reg [7:0] coloroutput; always #(pixel_tick) if(~video_on) coloroutput <= 0; else begin if(pixel_y<160) coloroutput[7:5] <= 3'b111; else if(pixel_y<320) coloroutput[4:2] <= 3'b111; else coloroutput[1:0] <= 2'b11; end assign red = (video_on)?coloroutput[7:5] : 3'b000; assign green = (video_on)?coloroutput[4:2] : 3'b000; assign blue = (video_on)?coloroutput[1:0] : 3'b000; endmodule
Searching your code for CLKIN_IN it only appears on the following line, which means there is nothing driving it ie connected to ground (GND). // Instantiate the module clkdiv instance_name ( .CLKIN_IN(CLKIN_IN), //<-- Not connected If variables are not declared logic/wire/reg/tri etc then a 1 bit wire is implied so you do not get the type checking of an unconnected port, it is however un-driven. Simulation should show this as a Z driving in.