How to generate PWL or pulse in verilog without using clock - verilog

I am working on a piece of code in which I need to generate output as per the condition-
1. if input is X/Z output should be X.
2. if input is 0 output should be 0 with a delay of 0.75us.
3. if input is 1 output should be 5 high going pulses of 1.5us with 50% duty cycle
with a delay of 0.75us.
I am confused How to write it in verilog?

You can use SystemVerilog's fork/join_none for this
logic in, out;
always begin
fork
case (in)
0: out <= #0.75us 0;
1: repeat (5) begin
#0.75us out <= 1;
#0.75us out <= 0;
end
default: out <= 'x;
endcase
join_none;
#in
disable fork; // kill repeat loop if still active
end

Related

Verilog LED Blinking no syntax errors. why it is not blinking

I wrote the program for blink 8 raw LEDs and code has not any errors and it is properly loaded. But blinking LEDs is not happen properly.
I checked pin planner and it was correct and clock I used is 50MHz. I am using the DE10 lite board.
module LED_blink(clk,led);
input clk;
output reg[7:0] led;
reg[31:0] count = 0;
always #(posedge clk)
begin
count <= count + 1;
led <= (count<50000000) ? 8'b11111111 : 0;
count <= (count<50000000) ? count : 0;
end
endmodule
There are no error messages but it is not working the way I assumed.
You should get the habit of simulating your code with a testbench before running it on an FPGA. But in this case even a simple Rubber Duck Debugging shows the errors.
When you execute count<=(count<50000000)?count:0; you override the previous count<=count+1;, thus the count will never increment.
This can be easily fixed by changing the 2 lines to:
count<=(count<50000000)?count+1:0;
The second problem is that led will be 0 only for one clock cycle (when count is equal to 50000000), practically you won't see any blinking.
This can be easily fixed by changing the line to:
led<=(count<25000000)?8'b11111111:0;
The problem is not syntactical, but there are some other problems in your code.
The first is the way you use nonblocking assignments (<=). In your code, all assignments will only be evaluated at the end of the clock cycle. Thus, the first line of your always block (count<=count+1) does not affect the last line of your always block (count<=(count<50000000)?count:0). Also, only the last line will be evaluated.
The second problem is that you don't have a reset state for count. The value is never explicitly set to 0, and you can therefore not know it's state.
If you fix these problems, there will be a third problem in your logic. You describe that your variable led should be 8'b11111111 if count is smaller than 50000000. However, as soon as the counter exceeds this value, you reset it to 0. In other words, your counter would always be smaller than 50000000, and led would never be set to 0.
I wrote down a small fix:
module LED_blink(clk,led);
input clk;
output reg[7:0] led;
reg[31:0]count=0;
always #(posedge clk or negedge rst_n)
begin
if (~rst_n) begin
count <= 32'b0;
led <= 8'b0;
end
else begin
count <= (count < 100000000) ? count + 1 : 0;
led <= (count < 50000000) ? 8'b11111111 : 0;
end
end
endmodule
Alternatively, you could write in your always block:
count <= (count < 50000000) ? count + 1 : 0;
led <= (count == 50000000) ? ~led : led;

How to find middle point between 2 pulses in Verilog in an FPGA?

I'm trying to find the mid-point between hsync pulses in a video stream. There are many "pixel clocks" in between hsync pulses. How can I get a pulse or signal exactly at the midpoint between two hsync pulses? Basically I want to be able to find the horizontal center of the screen. Here is what I have:
reg [30:0] count;
reg [30:0] counter;
wire left;
always #(posedge pixclk)
begin
if (hsync == 1'b1)
begin
count = counter;
counter = 1'b0;
end
else
begin
counter = counter + 1;
end
end
assign left = (counter < (count / 2) ? 1'b1 : 1'b0);
First, I don't know if this is conceptually the right way to do this.
Second, if hsync is held low for more than one pixclk cycle, then count will always be zero. It will only work if the width of hsync pulse is exactly one clock cycle or less.
First: You should use non-blocking assignments in a clocked section. <=
In your case you tell me that you have an hsync which is longer then your pixel clock.
One way is to count pulses when the hsync is low and store the result when it is high. That would require a small two-state Fine-State-Machine (FSM)
However I personally find making Fine-State-Machines a burden to be avoided. So here is what I would do:
Detect the edge of the hysnc (when it goes high or when it goes low) and count between the edges. Here is the core of the code:
reg hsync_one_cycle_delayed;
always #(posedge pixclk)
begin
hsync_one_cycle_delayed <= hsync;
if (hsync==1'b1 && hsync_one_cycle_delayed==1'b0)
// We have a detected a rising edge on hsync
begin
count <= counter;
counter <= 31'h0;
end
else
counter <= counter + 1;
end
Some final notes:
It assume the hsync is synchronous to the pixel clock.
This code has no reset which seems to become the norm in FPGA code, but which I personally deplore.

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.

registering and resetting the convolution output in verilog

so I have a module that does convolution, it takes a data input and the filter input , where input is array of 9 numbers , every posedge of the clk these two inputs are being multiplied and then added accumulatively, i.e I save every new multiplication product into a register. after each 9 iterations I have to save the result and reset it , but I have to do it in one clock cycle, since my new data is coming on the next posedge. So the issue that I am facing is how to not save data and reset the out without losing data? Please help if you have any suggestions. It also need to be mentioned that my conv_module is a sub-module and I will be instantiating it in a top module , so I have to access all the inputs and outputs from uptop.
This is the code that I've written so far, but it does not work the way I want it, cause I cannot tap the array of output numbers from the top module.
module mult_conv( input clk,
input rst,
input signed [4:0] a,
input signed[2:0] b,
output reg signed[7:0] out
);
wire signed [7:0] mult;
reg signed [7:0] sum;
reg [3:0] counter;
reg do_write;
reg [7:0] out_top;
assign mult = {{3{a[4]}},a} * {{5{b[2]}},b};
always #(posedge clk or posedge rst)
begin
if (rst)
begin
counter <= 4'h0;
addr <= 'h0;
sum <= 0;
do_write <= 1'b0;
end // rst
else
begin
if (counter == 4'h8)
begin // we have gathered 9 samples
counter <= 4'h0;
// start again so ignore old sum
sum <= mult;
out <= sum;
out_top <= out;
end
else
begin
counter <= counter + 4'h1;
// Add results
sum <= sum + mult;
out <= 0;
out_top <= out_top;
end
// Write signal has to be set one cycle early
do_write = (counter==4'h7);
end // clocked
end // always
endmodule
You have a plethora of errors in that code.
Apart from that you have a 3Mega bit memory from which you use only 1 in 9 locations.
You write out in two places. That does not work.
You use a %9. That can not be mapped onto hardware.
You have a sel signal which somehow controls your sum.
On top of that I understand you want to bring the whole memory out.
Your code because it needs to be drastically re-written.
But your biggest problem is that you definitely can't make the memory come out. What ever post-processing you want to do you have two choices:
Process the output data as it appears.
Store the data outside the module in a memory and have another process read that memory.
I think only (1) is the correct way because your signal can have infinite length.
As to fixing this code a bit:
Replace the %9 with a counter to count from 0 to 8.
Process out in in clocked section. See below
Move the addr and sel generating logic in here. Keep it all together.
Below is the basic code of how to do a 9-sequence convolution. I have to ignore 'sel' as I have no idea of the timing. I have also added address generation and a write signal so the result can be store in an external memory. But I still think you should process the result on the fly.
always #(posedge clk or posedge rts)
begin
if (rst)
begin
counter <= 4'h0;
addr <= 'h0;
sum <= 0;
do_write <= 1'b0;
end // rst
else
begin
if (counter == 4'h8)
begin // we have gathered 9 samples
counter <= 4'h0;
addr <= addr + 1;
// start again so ignore old sum
sum <= mult;
end
else
begin
counter <= counter + 4'h1;
// Add results
sum <= sum + mult;
end
// Write signal has to be set one cycle early
do_write = (counter==4'h7);
end // clocked
end // always
(Code above was entered on-the fly, may contain syntax, typing or other errors!!)
As you can see the trick is to know when to add the old result or when to ignore the old sum and start again.
(I spend about 3/4 of an hour on that so on my normal tariff you would have to pay me $93.75 :-)
I provided the basic code to let you work out the specifics. I did nothing with out but left that to you.
do_write and addr where for a possible memory to pick up the result. Without memory you can drop addr but do_write should tell you when a new convolution result is available, in which case you might want to give a it a different name. e.g. 'sum_valid'.

How to make an LED blink in Verilog?

I have a FPGA board and I'm trying to make an led blink with a 30% timing margin of 60 seconds.
I have the clock set at 24 MHz
Here is the code I used from a tutorial website
reg [33:0] counter;
reg state;
assign ledg[0] = state;
always # (posedge clock) begin
counter <= counter + 1;
state <= counter[24]; //
end
There are 3 concerns I have about this code:
I don't understand why the counter was declared with the subscript [33:0]
I don't understand why the state is set to unblock when counter[24]
Upon using this code, my timing margin is off, i.e. when I timed the amount of blinks per 60 seconds, it was 0.73, which is off by .03 according to the requirements.
Thanks
I don't understand why the counter was declared with the subscript [33:0]
The subscript [33:0] means that your counter has 34 bits. This means it can count from 0 to 2^(34)-1, or 0 to 17179869183 in decimal.
I don't understand why the state is set to unblock when counter[24]
Upon using this code, my timing margin is off, i.e. when I timed the
amount of blinks per 60 seconds, it was 0.73, which is off by .03
according to the requirements.
state is assigned to the 24th bit of the counter. That means that whenever the 24th bit of the counter is equal to 1, the state will be '1' and the LED will turn on. Whenever the 24th bit of the counter is 0, the state will be 0 and the LED will turn off.
Note that the 24th bit of the counter toggles every 2^24 cycles, or 16,777,216 cycles. Remember that your clock is 24 MHz so that means the clock toggles 24,000,000 times per second. So if your LED state toggles every 16,777,216 cycles, that means it toggles (16,777,216/24,000,000) times per second or every 0.699 second - so it should be very close to the 0.7 that you are looking for.
//300MHz to 1Hz
module top(
input clk,
input reset,
output led
);
reg [27:0] counter;
reg led;
reg clkout;
always #(posedge clk) begin
if (counter == 0) begin
counter <= 149999999;
clkout <= ~clkout;
end else begin
counter <= counter - 1;
end
end
always #(posedge clkout) begin
if (reset == 0) begin
led <= 0;
end else begin
led <= ~led;
end
end

Resources