Verilog How to change wire by bit with clock? - verilog

module clks(
input clk,
output [15:0] led
);
wire div2, div4, div8;
reg [2:0] count = 0;
assign div2 = count[0];
assign div4 = count[1];
assign div8 = count[2];
always #(posedge clk) count = count + 1;
endmodule
How can I turn on each led (I have 15 leds) using clock?
I'm really having trouble finding helpful resources online
initial begin
case({count})
2'b00:
led = 15'b000000000000001;
2'b01:
led = 15'b000000000000010;
...
endcase
end
This didn't work.
Or could I do something like this?
led = led + 1;

In your sample code above, you defined count as 3 bits, but your case statements are 2 bits wide. Also, you don't want the initial statement, rather use an always statement.
always # (count)
begin
case(count)
3'b000 : led = 15'b000_0000_0001;
3'b001 : led = 15'b000_0000_0010;
...
endcase
end

I guess that 'by using clock' means changing the led every clock cycle, right? Also it looks like you are trying to encode the led sequentially. In this case you can do the following:
you need to reset your lead to an initial value, sey 15'b1;
every clock cycle you can just shift it left by one. You should not do it in an initial block (though there is a technical way to do so). Use always blocks:
Here is an example:
module clks(
input clk,
input reset,
output reg [15:0] led
);
always #(posedge clk) begin
if (reset == 1)
led <= 15'b1;
else
led <= led << 1;
end
endmodule
In the above case '1' will travel through all bits of led over 15 clock cycles once. 'led' will become '0' after this. You have to make sure that it becomes '1' again if you want to continue in cycles.
Another possibility is to initialize 'led' in the always block, but it is not always synthesizable. YOu do not need a reset signal here.
initial led = 15'b1;
always #(posedge clk) led <= led << 1;

Related

multi-driven net, or reg not being driven

I'm working on an assignment where I need to create a jackpot game. But I'm having trouble driving the register that controls the win condition and I can't figure out why. As far as I know, the always#(posedge zero) block should be able to run whenever I flip my switch to the up position. Then, so long as the right hot register value happens in the same instant, it should be able to set the win register. However, this is not the case. Nothing seems to happen, and I'm not sure why. I've tried running the always block from different sensitivities but nothing seems to effect it. Maybe I'm just mis-understanding how always blocks work or how the switch works, any help is appreciated.
module jackpot(
input [3:0] SWITCHES,
output [3:0] LEDS,
input CLOCK,
input reset
);
reg [3:0] hot = 4'd1;
reg win;
wire clk, zero, one, two, three;
Clock_Div CDD (CLOCK, clk);
assign LEDS[2:0] = hot[2:0];
assign zero = SWITCHES[0];
assign one = SWITCHES[1];
assign two = SWITCHES[2];
assign three = SWITCHES[3];
assign LEDS[3] = zero;
initial begin
win <= 1'b0;
end
always #(posedge zero) begin
if(hot[0] && zero)
win <= 1'd1;
end
always #(posedge clk) begin
if (reset == 1'b1) begin
hot <= 4'd1;
win <= 1'd0;
end
else if(win == 1'b1) begin
hot <= 4'b1111;
end
else begin
if(hot == 4'b1000) begin
hot <= 4'b0001;
end
else begin
hot <= hot << 1;
end
end
end
endmodule
Thanks to Serge's comment I've realized the issue. Like his comment says, driving a register from multiple always blocks throws a critical warning, and Vivado picks one of the blocks to use over the other. Once I made sure to isolate a reg to an always block the behavior started to look like I expected. This must just be something that got glossed over during class, or maybe I wasn't paying attention enough.

How to program a delay in Verilog?

I'm trying to make a morse code display using an led. I need a half second pulse of the light to represent a dot and a 1.5 second pulse to represent a dash.
I'm really stuck here. I have made a counter using an internal 50MHz clock on my FPGA. The machine I have to make will take as input a 3 bit number and translate that to a morse letter, A-H with A being 000, B being 001 and so on. I just need to figure out how to tell the FPGA to keep the led on for the specified time and then turn off for about a second (that would be the delay between a dot pulse and a dash pulse).
Any tips would be greatly appreciated.
Also, it has to be synthesizable.
Here is my code. It's not functioning yet. The error message it keeps giving me is:
Error (10028): Can't resolve multiple constant drivers for net "c3[0]"
at part4.v(149)
module part4 (SELECT, CLK, CLOCK_50, RESET, led);
input [2:0]SELECT;
input RESET, CLK, CLOCK_50;
output reg led=0;
reg [26:0] COUNT=0; //register that keeps track of count
reg [1:0] COUNT2=0; //keeps track of half seconds
reg halfsecflag=0; //goes high every time half second passes
reg dashflag=0; //goes high every time 1 and half second passes
reg [3:0] code; //1 is dot and 0 is dash. There are 4 total
reg [1:0] c3; //keeps track of the index we are on in the code.
reg [3:0] STATE; //register to keep track of states in the state machine
reg done=0; //a flag that goes up when one morse pulse is done.
reg ending=0; //another flag that goes up when a whole morse letter has flashed
reg [1:0] length; //This is the length of the morse letter. It varies from 1 to 4
wire i; // if i is 1, then the state machine goes to "dot". if 0 "dash"
assign i = code[c3];
parameter START= 4'b000, DOT= 4'b001, DASH= 4'b010, DELAY= 4'b011, IDLE=
4'b100;
parameter A= 3'b000, B=3'b001, C=3'b010, D=3'b011, E=3'b100, F=3'b101,
G=3'b110, H=3'b111;
always #(posedge CLOCK_50 or posedge RESET) //making counter
begin
if (RESET == 1)
COUNT <= 0;
else if (COUNT==8'd25000000)
begin
COUNT <= 0;
halfsecflag <= 1;
end
else
begin
COUNT <= COUNT+1;
halfsecflag <=0;
end
end
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1)
COUNT2 <= 0;
else if ((COUNT2==2)&&(halfsecflag==1))
begin
COUNT2 = 0;
dashflag=1;
end
else if (halfsecflag==1)
COUNT2= COUNT2+1;
end
always #(RESET) //asynchronous reset
begin
STATE=IDLE;
end
always#(STATE) //State machine
begin
done=0;
case(STATE)
START: begin
led = 1;
if (i) STATE = DOT;
else STATE = DASH;
end
DOT: begin
if (halfsecflag && ~ending) STATE = DELAY;
else if (ending) STATE= IDLE;
else STATE=DOT;
end
DASH: begin
if ((dashflag)&& (~ending))
STATE = DELAY;
else if (ending)
STATE = IDLE;
else STATE = DASH;
end
DELAY: begin
led = 0;
if ((halfsecflag)&&(ending))
STATE=IDLE;
else if ((halfsecflag)&&(~ending))
begin
done=1;
STATE=START;
end
else STATE = DELAY;
end
IDLE: begin
c3=0;
if (CLK) STATE=START;
else STATE=IDLE;
end
default: STATE = IDLE;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: length=2'b01;
B: length=2'b11;
C: length=2'b11;
D: length=2'b10;
E: length=2'b00;
F: length=2'b11;
G: length=2'b10;
H: length=2'b11;
default: length=2'bxx;
endcase
end
always #(posedge CLK)
begin
case (SELECT)
A: code= 4'b0001;
B: code= 4'b1110;
C: code= 4'b1010;
D: code= 4'b0110;
E: code= 4'b0001;
F: code= 4'b1011;
G: code= 4'b0100;
H: code= 4'b1111;
default: code=4'bxxxx;
endcase
end
always #(posedge CLK)
begin
if (c3==length)
begin
c3<=0; ending=1;
end
else if (done)
c3<= c3+1;
end
endmodule
I have been reading your code and there are many issues:
The code is not formatted.
You did not provide a test-bench. Did you write one?
"Can't resolve multiple constant drivers for net" Search on stack exchange for the error message. It has been asked many times.
Use always #(*) not e.g. always #(STATE) you are missing signals like i, halfsecflag, ending. But see point 6: You want the STATE in a clocked section.
Where you use always #(posedge CLK) you must use non-blocking assignments: <=.
There are many places where you use always #(posedge CLK) where you want to use always #(*) (e.g. where you set length and code) Opposite you want to use a posedge CLK where you work with your STATE.
Use one clock and one clock only. Do not use CLK and CLOCK_50. Use either one or the other.
Take care of your vector sizes. This 8'd25000000 is wrong as you can no fit 25000000 in 8 bits.
Your usage of halfsecflag is excellent! I have see many times where people think they can use always #(halfsecflag) which is a recipe for disaster!
Below you find a small piece of your code which I have re-written.
All assignments are non-blocking <=
halfsecflag is essential to operate the code only every half a second, so I put that by itself in a separate if at the top. I would use that throughout the code.
All register are reset, both COUNT2 and dashflag.
dashflag was set to 1 but never set back to 0. I fixed that.
I specified the vector sizes. It makes the code "Lint proof".
Here is it:
always #(posedge CLOCK_50 or posedge RESET)
begin
if (RESET == 1'b1)
begin
COUNT2 <= 2'd00;
dashflag <= 1'b0;
end // reset
else if (halfsecflag) // or if (halfsecflag==1'b1)
begin
if (COUNT2==2'd2))
begin
COUNT2 <= 2'd0;
dashflag <=1'b1;
end
else
begin
COUNT2 <= COUNT2+2'd1;
dashflag <=1'b0;
end
end // clocked
end // always
Start fixing the rest of your code the same way. Write a test-bench, simulate and trace on a waveform display where things go wrong.
Normally you would build the finite state machine to produce the output. That machine would have some stages, like reading the input, mapping it to a sequence of morse code element, shifting out the elements to output buffer, waiting for conditions to move to the next morse element. You will need some timer that would produce one morse time unit intervals, and depending on the FSM stage you will wait one, three or seven time units. The FSM will spin in the waiting stage, it doesn't "magically" sleeps in some fpga-produced delay, there's no such things.
Okay a year later, I know exactly what one should do if they want to create a delay in their verilog program! Essentially, what you should do is create a timer using one of the clocks on your FPGA. For me on my Altera DE1-SoC, the timer I could use is the 50MHz clock known as CLOCK_50. What you do is make a timer module that triggers on the positive (or negative, doesn't matter) edge of the 50MHz clock. Set up a count register that holds a constant value. For example, reg [24:0] timer_limit = 25'd25000000; This is a register that can hold 25 bits. I've set this register to hold the number 25 million. The idea is to flip a bit every time the value in this register is exceeded. Here's some pseudocode to help you understand:
//Your variable declarations
reg [24:0] timer_limit = 25'd25000000; //defining our timer limit register
reg [25:0] timer_count = 0; //See note A
reg half_sec_clock;
always#(posedge of CLOCK_50) begin
if timer_count >= timer_limit then begin
reset timer_count to 0;
half_sec_clock = ~half_sec_clock; //toggle your half_sec_clock
end
Note A: Setting it to zero may or may not initialize count, it's always best to include a reset function that clears your count to zero because you don't know what the initial state is when you're dealing with hardware.
This is the basic idea of how to introduce timing into your hardware. You need to use an onboard clock on your device, trigger on the edge of that clock and create your own slower clock to measure things like seconds. The example above will give you a clock that triggers periodically every half second. For me, this allowed me to easily make a morse code light that could flash on either 1 half second count, or 3 half seconds. My best advice to you beginners is to work in a modular fashion. For example build your half second clock and then test it out to see if you can get a light on your FPGA to toggle once every half second (or whatever interval you want). :) I really hope this is the answer that helps you. I know this is what I was looking for when I originally posted this question so long ago.

Running into errors while trying to move signal to external module

I have two modules namely main.v and signal.v.
In main.v, I have a few lines of code that update 16 bit reg tx with a value corresponding to a square wave.
reg [1:0] counter;
reg [15:0] tx;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1) begin
tx[15:0] <= 16'b1010101010101010;
else
tx[15:0] <= 16'b0000000000000000;
end
This works fine. Eventually, though, I want to move this signal over to another file signal.v, because the signal that I pass to tx will grow steadily more complicated. I ran into errors when I try to do this. Initially, I tried to move all the above code to the file signal.v. Then used a wire between the two files as shown.
module signal(clk, get_tx);
input clk;
output reg get_tx;
reg [1:0] counter;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1) begin
get_tx[15:0] <= 16'b1010101010101010;
else
get_tx[15:0] <= 16'b0000000000000000;
end
Then in main.v, I tried to add
wire get_tx;
reg [15:0] tx;
signal my_signal(.clk(clk), .get_tx(get_tx));
always #( get_tx ) begin
tx <= get_tx;
end
Based on what I see in the output oscilloscope, this method isn't working, and I'm not certain why this is. The first case seems to work fine, so I don't know why it is failing when I move to the second case (the signals just look completely different).
I would appreciate any help/advice!
First of all will be better to understand your connections and simulate your code if you add full code with modules declarations. The problems are in the signal types. Try to change output to wire. As well you need to declare bus, not just 1 bit signal. And give an initial value to your counter (in other case it will do follow operation 'X' +1 which gives 'X' in result and your condition if (counter[1] == 1) will never be achieved).
module signal(clk, get_tx);
input clk;
output [15:0] get_tx;
reg [15:0] tx_out;
reg [1:0] counter = 2'd0;
always #(posedge clk) begin
counter = counter + 1;
if (counter[1] == 1)
tx_out[15:0] <= 16'b1010101010101010;
else
tx_out[15:0] <= 16'b0000000000000000;
end
assign get_tx = tx_out;
endmodule
Next error in upper module, there you also need to declare bus rather than just one bit wire [15:0] get_tx;. Try to fix this errors and your modules will work.

I2S Transmitter Verilog Implementation not working

I am trying to implement the I2S Transmitter in verilog. The datasheet for it is at: https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf
I wrote the code, but my SD line is delayed 1 clock cycle when i test it.
Can someone check my implementation?
module Transmiter(
input signed [23:0] DLeft, input signed [23:0] DRight, input WS, input CLK,
output reg SD
);
wire PL;
reg Q1,Q2;
reg [23:0] shift_reg;
reg [23:0] Tdata;
assign PL = Q1^Q2;
always #(posedge CLK)
begin
Q1 <= WS;
Q2 <= Q1;
end
always #( Q1) begin
if (Q1)
begin
Tdata <= DRight;
end
else
begin
Tdata <= DLeft;
end
end
always #(negedge CLK)
begin
if(PL)
begin
shift_reg <= Tdata;
end
else begin
SD <= shift_reg[23];
shift_reg <= {shift_reg[22:0],1'b0};
end
end
endmodule
EDIT: here is a image of waveform image
TEST BENCH CODE:
module Transmitter_tb(
);
reg CLK, WS;
reg [23:0] dataL;
reg [23:0] dataR;
wire SDout;
Transmiter UT(dataL, dataR, WS, CLK, SDout);
initial begin
dataL = 24'hF0F0FF; #2;
dataR = 24'h0000F0; #2;
end
always begin
CLK=0; #20;
CLK=1; #20;
end;
always begin
WS=0; #1000;
WS=1; #1000;
end;
endmodule
Your negedge block contains an if-else construct and will only ever compute one or the other on a single clock edge. SD will therefore not change value when PL is high.
Furthermore you are using non-blocking assignments(<=) in your code. This roughly means that changes won't be evaluated until the end of the always block. So even if SD <= shift_reg[23] after shift_reg <= Tdata it will not take on the new value in shift_reg[23] but use the previous value. If you want SD to change immediately when shift_reg[23] changes you need to do this combinatorically.
This should work:
always #(negedge CLK)
begin
if(PL)
begin
shift_reg <= Tdata;
end
else
shift_reg <= {shift_reg[22:0],1'b0};
end
assign SD = shift_reg[23];
Working example: https://www.edaplayground.com/x/4bPv
On a side note I am still not convinced that DRight and DLeft are in fact constants, I can see that they are in your TB but it doesn't make sense that the data for your I2S is constant. Your current construct will probably generate a latch(instead of a MUX), and we generally don't want those in our design.
You should clean up your use of blocking versus non-blocking statements:
Always use non-blocking assigments, meaning "<=", in clocked statements.
Always use blocking assigments, meaning "=", in combinational (non-clocked) statements.
This is a industry-wide recommendation, not a personal opinion. You can find this recommendation many places, see for instance:
http://web.mit.edu/6.111/www/f2007/handouts/L06.pdf
The sensitivtity list being incomplete (as pointed out by #Hida) may also cause issues.
Try to correct these two things, and see if it starts working more as expected.
Also note that you are using Q1 (among other signals) to generate your PL signal. If the WS input is not synchronous to your local clock (as I assume it is not), you need to put one more flop (i.e. two in series) before starting to use the output, to avoid metastability-issues. But you won't see this in an RTL simulation.

Verilog Array Walkthrough

I am just starting Verilog, and with little to no direction. I have been trying to build an 4 bit array that I want to walk through turning on and then off each of my LED's in order. I want them to go from 0-3, 7-4 and start over. I haven't set up my loops yet, however I want to see if I'm at least going in the right direction.
// 4 bit oscillating LED pattern
module count_osc (rstn, osc_clk, clk, LED);
input rstn;
output osc_clk;
output clk;
output [7:0] LED;
reg [22:0]c_delay;
genvar i;
genvar j;
GSR GSR_INST (.GSR(rstn)); // Reset occurs when argument is active low.
OSCC OSCC_1 (.OSC(osc_clk));
generate
for (i=0; i<4; i=i+1) begin : LED_loop
assign LED[i] = (clk);
for (j=4; j<8; j=j+1) begin : LED_loop_2
assign LED[j] = (~clk);
end
end
endgenerate
// The c_delay counter is used to slow down the internal oscillator (OSC) output
// to a rate of approximately 0.5 Hz
always #(posedge osc_clk or negedge rstn)
begin
if (~rstn)
c_delay <= 32'h0000;
else
c_delay <= c_delay + 1;
end
assign clk = c_delay[22];
endmodule
There are few misconceptions about verilog here, which are quite common for programmers coming from more procedural languages.
If your not aware Verilog describes hardware and therefore everything can happen in parallel, we do not procedurally start at the top and work our way through lines of code. Every initial and always blocks are running at the same time.
assign should be used outside of loops and it is a continuos assignment, ie combinatorial logic.
generate is used for parameterising hardware instances, you should not need this on basic examples. NB it also means that the hardware you describe can be quite tricky to understand.
With that in mind you may realise that this block:
generate
for (i=0; i<4; i=i+1) begin : LED_loop
assign LED[i] = (clk);
for (j=4; j<8; j=j+1) begin : LED_loop_2
assign LED[j] = (~clk);
end
end
endgenerate
Does not mean much, the first section is:
assign LED[0] = (clk);
assign LED[1] = (clk);
assign LED[2] = (clk);
assign LED[3] = (clk);
The second for loop is inside the first but only uses the second variable essentially overwriting the same statements 4 times:
assign LED[4] = (~clk);
assign LED[5] = (~clk);
assign LED[6] = (~clk);
assign LED[7] = (~clk);
When suggesting you write out what you want I was implying you write out the above instead of using generates.
Solution
I am not sure of the exact sequence you want from your question as you refer to a 4 bit array but uses 8 elements for the LED.
I think this might be a good place to practice creating a FSM (Finite state machine).
reg [2:0] state;
reg [2:0] nextstate;
always #(posedge clk or negede rst_n) begin
if (~rst_n) begin
state <= 'b0;
end
else begin
state<= nextstate;
end
end
//Next state logic (keeping it simple)
always #* begin
nextstate = state +1;
end
//Output logic
always #* begin
case(state)
3'd0 : LED = 'b0000_0000; //Binary makes sense as we can see the LED pattern
3'd1 : LED = 'b0000_0001;
3'd2 : LED = 'b0000_0011;
3'd3 : LED = 'b0000_0111;
3'd4 : LED = 'b0000_1111;
3'd5 : LED = 'b0000_0111;
3'd6 : LED = 'b0000_0011;
3'd7 : LED = 'b0000_0001;
default : LED = 'b0000_0000; //Default unreachable if we completed the case
endcase
end
I do not think this completes the sequence your trying to do but it should give enough of an understanding to complete the sequence yourself.

Resources