I'm making a simple project with leds blinking every second. Led 1 and 3 blink alternating to led 2 and 4. I've written the following Verilog code:
module leds_blinking(input i_Clk,
output o_LED_1,
output o_LED_2,
output o_LED_3,
output o_LED_4);
parameter c_CYCLESINSECOND = 50_000_000;
reg r_LED_1 = 1;
reg r_LED_2 = 0;
reg r_LED_3 = 1;
reg r_LED_4 = 0;
reg [32:0] r_Count = 0;
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else if (r_Count == c_CYCLESINSECOND)
begin
r_LED_1 <= ~r_LED_1;
r_LED_2 <= ~r_LED_2;
r_LED_3 <= ~r_LED_3;
r_LED_4 <= ~r_LED_4;
r_Count <= 0;
end
else
r_Count <= 0;
end
assign o_LED_1 = r_LED_1;
assign o_LED_2 = r_LED_2;
assign o_LED_3 = r_LED_3;
assign o_LED_4 = r_LED_4;
endmodule
All LEDs are active at the same time, though I instantiated 1,3 other than 2,4.
I’m assuming you are synthesizing and not running simulation on the RTL first. Synthesizer that target for ASIC typically ignore default values and initial blocks. Synthesizer that target for FPGA often do. Not knowing which synthesizer you are using it is hard to guess your root causes issue.
However, you can simplify your code and solve your problem by using one registers instead of four. Notice how the o_LED_# are driven.
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else
begin
r_LED <= ~r_LED;
r_Count <= 0;
end
end
assign o_LED_1 = r_LED;
assign o_LED_2 = ~r_LED;
assign o_LED_3 = r_LED;
assign o_LED_4 = ~r_LED;
Related
I wrote this I2C slave module in Verilog:
module I2CSlave(
input iSCL,
input iI2C_CLK,
inout bSDA,
output reg [7:0] odata,
output reg oread,
output wire oactive
);
reg incycle = 1'b0;
reg pSDA;
reg pSCL;
always #(posedge iI2C_CLK) begin
if ((pSCL) && (iSCL) && (pSDA) && (~bSDA)) begin
incycle <= 1;
end
if ((pSCL) && (iSCL) && (~pSDA) && (bSDA)) begin
incycle <= 0;
end
pSDA <= bSDA;
pSCL <= iSCL;
end
assign oactive = incycle;
localparam STATE_IDLE = 0;
localparam STATE_ADDR = 1;
localparam STATE_RW = 2;
localparam STATE_ACK = 3;
localparam STATE_DATA = 4;
localparam STATE_ACK2 = 5;
reg [7:0] i = 0;
reg [7:0] state = STATE_IDLE;
reg [6:0] addr = 7'h03;
reg addr_match = 1;
reg rw;
reg lSDA;
always #(posedge iSCL) lSDA <= bSDA;
assign bSDA = ((state == STATE_ACK) || (state == STATE_ACK2)) ? 0 : 1'bz;
assign oread = (state == STATE_ACK2);
assign ostate = i;
always #(negedge iSCL or negedge incycle) begin
if (~incycle) begin
state <= STATE_IDLE;
addr_match <= 1;
end
else if (addr_match) begin
case (state)
STATE_IDLE: begin
state <= STATE_ADDR;
i <= 7;
end
STATE_ADDR: begin
if (addr[i-1] != lSDA) addr_match <= 0;
if (i == 1) begin
state <= STATE_RW;
i <= i - 1;
end
else i <= i - 1;
end
STATE_RW: begin
rw <= lSDA;
state <= STATE_ACK;
end
STATE_ACK: begin
state <= STATE_DATA;
i = 7;
end
STATE_DATA : begin
odata[i] <= lSDA;
if (i == 0) state <= STATE_ACK2;
else i <= i - 1;
end
STATE_ACK2: begin
state <= STATE_DATA;
i = 7;
end
endcase
end
end
endmodule
As of now it should just read the data sent by master. It seems to work well in simulation, but when I upload it into the FPGA, sometimes everything is OK, however sometimes it does not acknowledge the data sent by master and it just seems to ignore them. I am newbie in Verilog, so I hope, this is not a silly question.
One possible cause for random fails while running on real hardware is that you didn't synchronize inputs.
You are sampling slowly changing signals (i2c bus will have a long slopes) that are truly asynchronous to your design's clock. Depending on your luck, you will have random violations for setup/hold times of your fpga's d-flops, which results in metastability issues. The same value in the register might be treated differently in multiple parts of the chip. That will wreak havoc in your i2c slave's logic.
You must synchronize asynchronous inputs, in the simplest case passing it through a couple of registers before feeding it to the module's fsm.
You have several issues with your code which could cause mismatch in behavior in simulation and synthesis. For example, the following is not synthesizable and is ignored by synthesis tools. So, your initial state would be different. Check your logs for warnings. Do not use declaration assignments for regs. (ok for wires).
reg [7:0] i = 0;
reg [7:0] state = STATE_IDLE;
reg [6:0] addr = 7'h03;
reg addr_match = 1;
The above means that you initialization does not work.
You messed up blocking and non-blocking assignments in the state machine. Make sure that you use nbas in all places where 'i = 7'. it should be
i <= 7;
And make sure that you test enough initialization and different conditions in simulation.
I am trying to do a VGA output using verilog but I can't seem to figure out why r_hcount stays X. The simulation waveforms show that r_vcount is being reset to 0 properly but for some reason r_hcount never gets reset to 0. I can't figure out why...
Verilog code:
module m_VGA640x480(
input wire iw_clock,
input wire iw_pix_stb,
input wire iw_rst,
output wire ow_hs,
output wire ow_vs,
output wire ow_blanking,
output wire ow_active,
output wire ow_screenend,
output wire ow_animate,
output wire [9:0] ow_x,
output wire [9:0] ow_y
);
localparam HS_STA = 16;
localparam HS_END = 16 + 96;
localparam HA_STA = 16 + 96 + 48;
localparam VS_STA = 480 + 11;
localparam VS_END = 400 + 11 + 2;
localparam VA_END = 480;
localparam LINE = 800;
localparam SCREEN = 524;
reg [9:0] r_hcount;
reg [9:0] r_vcount;
assign ow_hs = ~((r_hcount >= HS_STA) & (r_hcount < HS_END));
assign ow_vs = ~((r_vcount >= VS_STA) & (r_vcount < VS_END));
assign ow_x = (r_hcount < HA_STA) ? 0 : (r_hcount - HA_STA);
assign ow_y = (r_vcount >= VA_END) ? (VA_END - 1) : (r_vcount);
assign ow_blanking = ((r_hcount < HA_STA) | (r_vcount > VA_END - 1));
assign ow_active = ~((r_hcount < HA_STA) | (r_vcount > VA_END - 1));
assign ow_screenend = ((r_vcount == SCREEN - 1) & (r_hcount == LINE));
assign ow_animate = ((r_vcount ==VA_END - 1) & (r_hcount == LINE));
always #(posedge iw_clock)
begin
if (iw_rst)
begin
r_hcount <= 0;
r_vcount <= 0;
end
if (iw_pix_stb)
begin
if (r_hcount == LINE)
begin
r_hcount <= 0;
r_vcount <= r_vcount + 1;
end
else
r_hcount <= r_hcount + 1;
if (r_vcount == SCREEN)
r_vcount <= 0;
end
end
endmodule
Here is the result of the simulation. r_hcount is bugged... The code is supposed to set both counters to 0 when reset is 1 but for some reason it's not getting reset to 0. Please help.
Wavefrorm
From your work, I notice one point may cause the issue
always #(posedge iw_clock)
begin
if (iw_rst)
//you define r_hcount <= 0 here
.....
if (iw_pix_stb) //<== another condition
// r_hcount <= 0 is also defined here
So if posedge clock happened, r_hcount may be bugged here.
I suggest it should be done like this
else if (iw_pix_stb) <=== else if here
Good luck.
After tinkering a bit more with the code, I found out that it was because r_hcount <= 0 was getting overridden by r_hcount <= r_hcount + 1 which will set r_hcount to X. This was caused because the two clock inputs were both the same frequency.
I should be more careful in the future...
Im trying to implement 4 clock signals that are activated one after the other in Verilog. I've written a module but Im not sure how to make a testbench for it because Im getting the error:
error: clk_pc Unable to assign to unresolved wires.
I expect a result like this one:
1000
0100
0010
0001
1000
0100
...
This is the module:
module clock_divisor(input clk0,
input clk1,
input clk2,
input clk3,
output clk0_out,
output clk1_out,
output clk2_out,
output clk3_out);
reg clk0_out,clk1_out,clk2_out,clk3_out;
always #(posedge clk0 or posedge clk1 or posedge clk2 or posedge clk3) begin
if(clk0 == 1)begin
assign clk0_out = 0;
assign clk1_out = 1;
assign clk2_out = 0;
assign clk3_out = 0;
end
else if(clk1 == 1)begin
assign clk0_out = 0;
assign clk1_out = 0;
assign clk2_out = 1;
assign clk3_out = 0;
end
else if(clk2 == 1)begin
assign clk0_out = 0;
assign clk1_out = 0;
assign clk2_out = 0;
assign clk3_out = 1;
end
else if(clk3 == 1)begin
assign clk0_out = 1;
assign clk1_out = 0;
assign clk2_out = 0;
assign clk3_out = 0;
end
end
endmodule
And my testbench:
module testbench();
reg clk_pc, clk_instruction_memory, clk_alu, clk_registers, reset;
// Clock Management
clock_divisor clock_divisor (clk_pc,
clk_instruction_memory,
clk_alu,
clk_registers,
clk_pc,
clk_instruction_memory,
clk_alu,
clk_registers);
initial begin
clk_pc = 1;
end
initial
#500 $finish;
initial begin
//$display (" Pc\tCLK\treset\tCurrent-inst");
//$monitor(" %d\t%b\t%b\t%h", pc, clk_pc, reset, current_instruction);
//Monitor Clocks
$display (" CLK0\tCLK1\tCLK2\tCLK3");
$monitor(" %b\t%b\t%b\t%b", clk_pc, clk_instruction_memory, clk_alu, clk_registers);
end
endmodule
Can anyone tell me why Im getting this error and how can I get my module to work as expected?
(sorry, my reputation is too low to comment)
Like others said, do not use procedural assignments in always blocks. Sequential elements must only have non-blocking assignments (<=) and combinatorial elements only blocking assignments (=). Don’t mix them within a code block. Also, your design will not synthesize due to multiple signals in always block sensitivity list.
If you want to synchronize your clock signals, just use one of them and sync others to it. This is plain simple if you use a 4-bit rotating shift register and assign clock outputs to a corresponding bit in the shift register.
Shift Register:
module clock_divisor(input clk0,
input rst_i,
output clk0_out,
output clk1_out,
output clk2_out,
output clk3_out);
reg [3:0] shift_reg;
always # (posedge clk0 or negedge rst_i) begin
if(rst_i) begin
shift_reg <= 4'd1;
end
else begin
shift_reg <= {shift_reg[2:0], shift_reg[3]};
end
end
assign clk0_out = shift_reg[0];
assign clk1_out = shift_reg[1];
assign clk2_out = shift_reg[2];
assign clk3_out = shift_reg[3];
endmodule
Frequency of all clock outputs is the same as clk0! They just have a 180° phase shift.
But if you really want to make a clock divider, just use a simple counter:
module clock_divisor(input clk0,
input rst_i,
output clk0_out,
output clk1_out,
output clk2_out,
output clk3_out);
reg [3:0] counter;
always # (posedge clk0 or negedge rst_i) begin
if(rst_i) begin
counter <= 4'd0;
end
else begin
counter <= counter + 1'd1;
end
end
assign clk0_out = counter[0];
assign clk1_out = counter[1];
assign clk2_out = counter[2];
assign clk3_out = counter[3];
endmodule
Now, frequency of clk_out's are:
clk0_out = 2*clk0
clk1_out = 4*clk0
clk2_out = 8*clk0
clk3_out = 16*clk0
Hope this helps you!
P.S. Do not forget to add reset signal for registers! This is crucial, so your design can start from a known state.
I'm very new to verilog and I am stuck on a project I am writing to get better at it. I have a button and an LED on my board, and I want the button to increment a counter which makes the led flash faster. This seems to work in theory but I cannot get it to work in practice. The switch won't make the led flash faster, it seems to do some strange things.
My current code, please inform me of any issues with what I'm doing even if it does not cause my issue here as I am trying to learn the langauge and constructs.
`timescale 1ns / 1ps
module LedFlash(CLK100MHZ, led0, sw0, btn0);
input CLK100MHZ;
output reg led0;
input sw0;
input btn0;
reg [25:0] clockTick = 0;
reg [1:0]currentlyLighting = 0;
reg [3:0] speedFactor = 0;
reg [1:0]oldButton = 0;
reg [1:0]buttonValue = 0;
always #(posedge CLK100MHZ)
begin
led0 <= 0;
buttonValue <= 0;
if(oldButton != btn0 && btn0 == 1)
buttonValue <= 1;
oldButton <= btn0;
if(clockTick == 0)
currentlyLighting <= !currentlyLighting;
if(currentlyLighting)
led0 <= 1;
if(buttonValue) begin
speedFactor <= speedFactor + 1;
end
clockTick <= clockTick + speedFactor;
end
endmodule
Here is a gif of a couple presses of the button. Only the times when speedfactor increments is when I actually press the button.
I would provide more presses, but it just gets more strange from there, clearly I am doing something wrong.
After that initial press of the button, it strays away from what I expect. Sometimes it turns off, sometimes stays solid, slows down, speeds up.....
**Also, if I replace this line :
clockTick <= clockTick + speedFactor;
with
clockTick <= clockTick + 10;
for example, it will flash fast like I would expect it to. I'm guessing I am doing something wrong with the bit addition, although the probe seems to tell me otherwise.
**
Fixed code :
`timescale 1ns / 1ps
module LedFlash(CLK100MHZ, led0, sw0, btn0);
input CLK100MHZ;
output reg led0;
input sw0;
input btn0;
reg [25:0] clockTick = 0;
reg currentlyLighting = 0;
reg [3:0] speedFactor = 0;
reg oldButton = 0;
reg buttonValue = 0;
always #(posedge CLK100MHZ)
begin
led0 <= 0;
buttonValue <= 0;
if(oldButton != btn0 && btn0 == 1)
buttonValue <= 1;
oldButton <= btn0;
currentlyLighting <= clockTick[25];
if(currentlyLighting && sw0)
led0 <= 1;
if(buttonValue) begin
speedFactor <= speedFactor + 1;
end
clockTick <= clockTick + speedFactor;
end
endmodule
The design doesn't ensure that clockTick hits 0 while starting a new round, so speedFactor actually cannot control the toggling frequency of currentlyLighting.
For example, if clockTick is 26'h3FFFFFF and speedFactor is 4'd3, the next value of clockTick will be 26'h0000002 and currentlyLighting will not toggle for that round.
An easy solution could be using the MSB of clockTick as currentlyLighting.
currentlyLighting <= clockTick[25];
In addition; buttonValue, oldButton and currentlyLighting should be single-bit signals, but they are 2-bit in your code. The correct declarations are as follows.
reg currentlyLighting = 0;
reg oldButton = 0;
reg buttonValue = 0;
This is code for ALU that does addition and multiplication only. An addition is handled in same clock cycle but the multiplication result has to be delayed by 3 clock cycles.
module my_addmul(
//control signals
input i_clk,
input i_rst,
input i_en,
//add=01, mul=10
input [1:0] i_op,
//input and output registers
input [31:0] i_A,
input [31:0] i_B,
output [31:0] o_D,
//to signal if output is valid
output o_done
);
//registers to save output
reg [31:0] r_D;
reg [63:0] r_mul;//(*keep="true"*)
reg r_mul_done;
reg r_mul_done2;
reg r_done;
//updating outputs
assign o_D = r_D;
assign o_done = r_done;
always # (posedge i_clk)
begin
r_done <= 0;
r_mul_done <= 0;
if (i_rst) begin
r_D <= 0;
r_mul <= 0;
r_mul_done <= 0;
r_mul_done2 <= 0;
end else if (i_clk == 1) begin
if (i_en == 1) begin
//addition - assignment directly to OP registers
if (i_op == 01) begin
r_done <= 1;
r_D <= i_A + i_B;
//multiplication - indirect assignment to OP registers
end else if (i_op == 2'b10) begin
r_mul <= i_A * i_B;
r_mul_done <= 1;
end
end
//1-clock cycle delay
r_mul_done2 <= (r_mul_done == 1) ? 1 : 0;
//updating outputs in the 3rd cycle
if (r_mul_done2 == 1) begin
r_D <= r_mul[31:0];
r_done <= 1;
end
end
end
endmodule
The problem is that if the keep attribute is not used, the r_mul register that stores the multiplication output until 3rd clock cycle is optimised out. I read on the problem and realised that Vivado is thinking like this: "If the multiplication happens every clock cycle, the r_mul is over-written before it is sent to output. Therefore, it is a register being written but not read, Lets remove it!" Since I insert the 3 clock cycle wait in test bench, the simulation result is always accurate. I want to know what is the "Proper" way of doing this so I don't have to use the keep attribute. It is an ok solution but I think useful techniques should be learned so hacks don't have to be used. Any ideas or discussion welcome.
If I want to delay a signal, I'd probably insert flops for that. You can probably flop your mul_output like the way you do for the mul_done signal. Also, it is better to have different always blocks for doing the same. You can check the code below but it might be buggy since I haven't simulated/synthesized it -
module my_addmul(
//control signals
input i_clk,
input i_rst,
input i_en,
//add=01, mul=10
input [1:0] i_op,
//input and output registers
input [31:0] i_A,
input [31:0] i_B,
output [31:0] o_D,
//to signal if output is valid
output o_done
);
//registers to save output
reg [31:0] r_D;
reg [63:0] r_mul;//(*keep="true"*)
reg r_mul_1;
reg r_mul_2;
reg r_mul_done;
reg r_mul_done2;
reg r_done;
//updating outputs
assign o_D = r_D;
assign o_done = r_done;
always # (posedge i_clk)
begin
r_done <= 0;
r_mul_done <= 0;
if (i_rst) begin
r_D <= 0;
r_mul <= 0;
r_mul_done <= 0;
r_mul_done2 <= 0;
end else if (i_clk == 1) begin
if (i_en == 1) begin
//addition - assignment directly to OP registers
if (i_op == 01) begin
r_done <= 1;
r_D <= i_A + i_B;
//multiplication - indirect assignment to OP registers
end else if (i_op == 2'b10) begin
r_mul <= i_A * i_B;
r_mul_done <= 1;
end
end
end
end
always # (posedge i_clk)
begin
if (i_rst)
begin
r_mul_1 <= 0;
r_mul_done2 <= 0;
end
else
begin
r_mul_1 <= r_mul;
r_mul_done2 <= r_mul_done;
end
end
always # (posedge i_clk)
begin
if (i_rst)
begin
r_D <= 0;
r_done <= 0;
end
else
begin
r_D <= r_mul_1;
r_done <= r_mul_done2;
end
end
endmodule