I need to generate a waveform, as shown in the image. But with my code, I did not get expected waveform
In the design, part got the last and valid values in a random period from test-bench.
my problem is why the I value incremented at valid not equal to one
Design code:
module design_d(clk,valid,last,data);
input clk,valid,last;
output reg [7:0] data;
reg [7:0] i;
initial
begin
data=0;
i=0;
end
always #(posedge clk,valid)
begin
if (valid)
begin
data<=i;
i=i+1;
$display("i=%d data=%d ",i,data);
end
else
begin
data <=8'bz;
end
end
endmodule
Test bench code:
module test;
reg clk,valid,last;
wire [7:0] data;
parameter clk_period=2;
design_d dut(clk,valid,last,data);
initial
begin
clk=1;
valid=1;
last=0;
end
always #(clk_period/2) clk=~clk;
always #(posedge clk)
begin
last=0;
#4 last=1;
#clk_period last=0;
#8 last=1;
#clk_period last=0;
#10 last=1;
#clk_period last=0;
#16last=1;
#clk_period last=0;
#20 last=1;
#clk_period last=0;
end
always #(posedge clk or last)
begin
valid<=1;
wait(last==1)
#clk_period;
valid<=0;
#clk_period;
valid<=1;
end
initial
begin
$dumpfile("dump.vcd");
$dumpvars(1);
#24 $finish;
end
endmodule
It seems you have difficulties with the English language, which is not your fault but because of that, I may interpret your question wrongly.
You have a waveform of what you need to achieve. This to me suggest that this is a school assignment and therefore I will treat it that way. This means I will **not* give you a complete answer but give you pointers about where you are going wrong. (This should all be in a comment but there is now way it would fit).
...got the last and valid values in a random period from test-bench.
First thing to realize is writing a test-bench is just as difficult, if not more difficult then writing the RTL code itself.
In your test-bench You are using always #(posedge clk) but inside that section you use #... statements. That by itself is not wrong. Dangerous, yes, but not necessary wrong.
But
Your clock has a time period of 2 (parameter clk_period=2;) and inside your posedge clock you use delays which are equal or bigger then the clock period. That often leads to a disaster, as you have found out.
Read up on how Verilog works, especially when the sensitivity list always #... is used: It is not triggered until all statement in the section have been dealt with. In your case it means the that it will takes several clock edges until the always block is started again.
Test Bench
I don't know what the assignment was so I'll use the waveform you have given.
As last and valid are inputs to you module I will give you pointers how to make those.
valid is high for 4 clock cycles, it is then low for one clock cycle, after which it repeats itself. This means you need a pattern which repeats itself every 5 clock cycles and thus you need to make a counter which counts 0,1,2,3,4,0,1,2,3,4,...
You should not make that using #..... statements. You should use the test bench clock and make a counter which counts!
Making a counter which counts as described above is the first thing you need to learn in HDL! You will find that you have to do that over and over and over and over .. In every piece of RTL code and every test bench.
Modulo 5 counter.
I prefer for all my modules and my test benches to have a reset.
If only that it allows me to start a new test from a known state.
reg [2:0] counter;
always #(posedge clk or negedge reset_n)
begin
if (reset_n)
counter <= ...
else // clocked section
begin
if (..)
counter <= ...
else
counter <= ...
end
end
Start fresh and get the above code running first. Observe that the counter is indeed running 0,1 2, 3, 4, 0, .. before you continue.
Derived signals .
Next learn to derive signals from that.
Basic rule: in a clocked section, if you need a signal at counter value X you have to generate that at cycle X-1.
Thus to make last high when the counter is 3 you have to set that up when the counter is 2:
always #(posedge clk...
...
if (counter==3'h2)
last <= 1'b1;
else
last <= 1'b0;
I leave making the valid to you.
Once you got your test bench running start working on your design_d module.
Some tips:
Use always non-blocking assignments <= in your clocked section. **
Do NOT use a clock period of 2, use 100 or 1000. You will find out in due time why that is better.
Do not use always #(posedge clk or [one or more signals] ) unless as per my example. **
Take care of your indenting. I had to do some mayor editing on your code.
**Sorry I can't go into details why that is good practice most of the time as that would triple the size of this answer. For now please follow the tips.
I could have written the actual code in a tenth of the time it took me to write all that so I hope you will not delete the question as others may profit from it.
Related
I'm a bit of a neophyte with Verilog, and I have just started working on a project, and I'm trying to verify that the code I have started with is workable. The code snippet below is unloading a FIFO into a vector of 8 bit registers. At each clock cycle it unloads a byte from the FIFO and puts it in the end of the register chain, shifting all the other bytes down the chain.
reg [ 7:0] mac_rx_regs [0 : 1361];
generate for (ii=0; ii<1361; ii=ii+1)
begin: mac_rx_regs_inst
always #(posedge rx_clk_int, posedge tx_reset)
if (tx_reset) begin
mac_rx_regs[ii] <= 8'b0;
mac_rx_regs[1361] <= 8'b0;
end else begin
if (rx_data_valid_r) begin
mac_rx_regs[ii] <= mac_rx_regs[ii+1];
mac_rx_regs[1361] <= rx_data_r;
end
end
end
endgenerate
I'd like to know if this is a good way to do this. I would have expected to just address the register vector with the byte count from reading the FIFO. I'm concerned that this isn't deterministic in that the order that the generated always blocks run is not specified, plus it seems that it'll cause a lot of unnecessary logic to be created for moving data from one register to another.
To start with, you don't really need to worry about the number of always statements in general. If they are all using the same clock and reset, you will get expected behavior relative to interaction between the processes.
The one thing I do, that is more about style than anything else, is to add a #FD to my flop assignments like shown below to make simulation look a little better, IMHO.
Also, this is simple enough that you could code this as a single process.
parameter FD = 1;
reg [1361*8-1:0] mac_rx_regs; // Arrays are good if you are trying to
// infer memory, but if you are okay
// with registers, just declare a vector.
always # (posedge clk or posedge reset)
begin
if (reset)
mac_rx_regs <= #FD 1361*8'h0;
else
// This next statement shifts in a new 8 bits when rx_data_valid_r is asserted.
// It will assign max_rx_regs to max_rx_regs (nop) when deasserted.
mac_rx_regs <= #FD rx_data_valid_r ? {mac_rx_regs[1361*8-9:0],rx_data_r} :
mac_rx_regs;
end
So, im trying to synthesize my verilog code to send data from ps2 keybord ->fpga->vga. Just for the background of the code, I want to press the button "1", and that to appear on the center of the screen (called the display_area)
I realised that something is not working as expected.
After carefull debugging, i realised that the problem lies in the module that converts the parallel data bus from the rom, into serial output, to assign a value in each pixel.
The code itself is pretty simple, im just providing as much info as i can.
We need a positive edge of the clock to enter the always area (or a reset). If the value display_area_enable is 1, we activate a counter from 7 till 0 (8 cycles) to index the data from the rom.
However, on the first clock, if the display area becomes 1 the exact moment when the vga_clk pulse becomes 1, the counter gets the value as it should, but the one_bit_output (the output of the module) doesnt. One_bit_output gets its first correct value the 2nd time that the always block is accessed. as a result we need 9 cycles to access an 8 bit bus.
I ll provide the code and a modelsim testbench
module shifter(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
input [7:0]char_rom_data_out;
input vga_clk,display_area_enable,reset;
output reg one_bit_output;
output reg [2:0]counter;
always #(posedge vga_clk or posedge reset)
begin
if (reset)
begin
counter=3'd7;
one_bit_output=0;
end
else if (display_area_enable==1)
begin
one_bit_output<=(char_rom_data_out[counter]==1);
counter<=counter-1;
end
else if (display_area_enable==0)
begin
counter<=3'd7;
one_bit_output<=0;
end
end
endmodule
module testbz();
reg reset,vga_clk,display_area_enable;
reg [7:0]char_rom_data_out;
wire [2:0] counter;
wire one_bit_output;
shifter dignitas(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
initial
begin
reset<=1; char_rom_data_out<=8'b11110001; vga_clk<=0;display_area_enable=0; //sto 10 skaei o prwtos kyklos, kai meta ana 20
#5 reset<=0; display_area_enable<=0;
#5 display_area_enable<=1;
#160 display_area_enable<=0;
end
always
begin
#10 vga_clk=~vga_clk;
end
endmodule
and the simulation is :
Can someone explain to me why on the first pulse of the vga_clk, the output is not expected?
Change one_bit_output so that it does not change in relation to the clock edge, but asynchronously in relation to the display_area_enable. The counter keeps track of which element to output. This is essentially a multiplexer with display_area_enable as the selector, or more likely an AND gate with one input being display_area_enable.
As toolic said, the synchronous one_bit_output cannot change on the same cycle as its activating signal. This is because of the set-up times of the flip-flops, the signal must be stable for some time before the clock edge. Now, if you are using one_bit_output to drive some flip-flop, then it MUST update on the next edge. Don't try to avoid this by using latches, that will make synthesis quite hard.
module shifter(reset,char_rom_data_out,vga_clk,display_area_enable,one_bit_output,counter);
input [7:0]char_rom_data_out;
input vga_clk,display_area_enable,reset;
output reg one_bit_output;
output reg [2:0]counter;
always #(posedge vga_clk or posedge reset)
begin
if (reset)
begin
counter<=3'd7;
//one_bit_output<=0;
end
else if (display_area_enable==1)
begin
//one_bit_output<=(char_rom_data_out[counter]==1);
counter<=counter-1;
end
else if (display_area_enable==0)
begin
counter<=3'd7;
//one_bit_output<=0;
end
end
assign one_bit_output = display_area_enable ? char_rom_data_out[counter] : 0;
endmodule
I know the question sounds strange and vague, but I got a problem getting around the Verilog.
I got a FSM which has to use a 4 7 segment displays, at one state it should show only one number on one display, at other it should use all 4 displays to display a string.
My question is how can I actually get around the always# blocks with this kind of problem.
I've tried setting in one always# two different cases in a If else block, but it didn't work out. Tried also making two modules one for the number and the other for the string, assigning different output ports but the thing is that it has to point to the same hardware ports, and it fails on the bitstream.
Could someone of you give me some tips?
Ok, I will post some code, but the main picture is that I have a master state machine and then I got another state machine. Depending on the state of the other FSM I output state number on the display. But in a different state of the master state machine I have to display a message on the 4 7segment displays. What I got now is:
Here I used CLK in order to make the message
always#(BIN_IN or CLK) begin
if(FAIL==1) begin
case(state)
left:
begin
HEX_OUT [6:0] <= F;
SEG_SELECT_OUT <= 4'b0111;
state <= midleft;
end
midleft:
begin
HEX_OUT [6:0] <= A;
SEG_SELECT_OUT <= 4'b1011;
state <= midright;
end
//same for the rest
end
else begin
case (BIN_IN)
4'h0 : begin
HEX_OUT [6:0] <= 7'b1000000;
SEG_SELECT_OUT <= 4'b0111;
end
//same logic for the other cases
Board used is Xilinx Basys 3 using vivado synthesising tool
Thanks
As Greg said:
always#(BIN_IN or CLK)
Infers combinational logic. An FSM cannot be created with combinational logic alone. As you know, a FSM needs to be able to store the state between each clock.
always#(posedge CLK)
Infers flipflops into your design. That is, the operations you do inside this always loop will be stored until the next positive edge. If you put all of the design inside this always block you will end up with a typical moore-machine where your outputs will only update on every positive clock edge.
It is a bit hard to understand what you are trying to create from your code-snippet. You are talking about two FSM's, but it seems to me that you are trying to do one combinational operation and one clocked operation. If you want your design to update some outputs - like BIN_IN - combinationally(that is, immediately) you have to do these assignments outside of the always#(posedge CLK) block. Use a always#(posedge CLK) block to update your FSM-values and then use a combinational always#(BIN_IN or FAIL) block to infer a multiplexer that will choose between your FSM-output and other outputs. Something like this might work:
always#(posedge CLK)
begin
case(state)
left:
begin
FAIL_HEX_OUT <= "A";
FAIL_SEG_OUT <= 4'b1011;
state <= midleft;
end
//Rest of statements
endcase
end
always#(FAIL or BIN_IN or FAIL_SEG_OUT or FAIL_HEX_OUT)
begin
if(FAIL == 1) begin
HEX_OUT <= FAIL_HEX_OUT;
SEG_SELECT_OUT <= FAIL_SEG_OUT;
end else begin
case(BIN_IN)
//your statements
endcase
end
end
Additionally, this wont work:
HEX_OUT [6:0] = A;
do this to assign ascii to a reg
HEX_OUT [6:0] = "A";
I also assume that you are using endcase to close your case-statements.
I have made your code-snippet compile here:
http://www.edaplayground.com/x/P_v
Edit:
I changed the sensitivity list on the combinational logic. The above code wouldn't have worked earlier.
Because you have posted so little of your code it is hard to figure out what you actual problem is. I assume that you only have one output port for to control all the 7-segment displays. In that case you need to cycle through each SEG_SELECT_OUT and set HEX_OUT for each display when you wish to output FAIL. This, in turn, implies that each display also has the ability to store the HEX_OUT signal that it receives, and your outputs (probably SEG_SELECT_OUT) must enable the write functionality of these display registers. Check that this is the case. I also assume that your real-time-counter that counts 30 seconds sets the FAIL flag when it completes, and is reset every time the maze(I have no idea what you mean when you say maze) is completed. You say that you need to change the number, and I assume that you are talking about outputting the number in BIN_IN on your display and that BIN_IN is changed elsewhere. All of this should work in the code above.
Without more information it is hard to help any further.
Hello Friends I still not know how to Generate Delay in Verilog For synthesis and call it any line in Verilog for synthesis...for finding this I write a code but it not works please help me if you know how to Generate Delay and call in any line like a C's Function*......Actually Friends if you tell me why I use for Loop here then my answer is - I want to move pointer inside for loop until and unless they completes its calculation that I made for Delay Generation..
module state_delay;
reg Clk=1'b0;
reg [3:0]stmp=4'b0000;
integer i,a;
always
begin
#50 Clk=~Clk;
end
always #(posedge Clk)
begin
a=1'b1;
delay();
a=1'b0;
delay();
a=1'b1;
end
task delay();
begin
for(i=0;i==(stmp==4'b1111);i=i+1)
begin
#(posedge Clk)
begin
stmp=stmp+1;
end
end
if(stmp==4'b1111)
begin
stmp=4'b0000;
end
end
endtask
endmodule
Actually friends I want this a=1'b0; delay(); a=1'b1; please help I already tried delay Generation Using Counter previously but it not works for me.....If you know same using Counter then please tell me......Thanks
// will generate a delay of pow(2,WIDTH) clock cycles
// between each change in the value of "a"
`define WIDTH 20
reg [`WIDTH:0] counter;
wire a = counter[`WIDTH];
always #(posedge Clk)
counter <= counter + 1;
You have to choose a suitable value for WIDTH according to how much delay you want between changes in a and the rate of your Clk signal
This question is a more succinct version of How to generate delay in verilog using Counter for Synthesis and call inside Always block?.
There is one section of code that I find troublesome:
always #(posedge Clk) begin
a = 1'b1;
delay() ;
a = 1'b0;
end
NB: A good rule to stick to is to always use <= in edge triggered processes.
for now lets think of the delay(); task as #10ns; What we get with the current code would be:
time 0ns a = x;
time 1ns a = 1; //Posedge of clk
time 6ns a = 1; //Waiting on delay
time 11ns a = 0; //Delay completed
Using <= and I think you should see a similar behaviour. However when it comes to synthesis delays like #1ns can not be created and the whole thing will collapse back down to :
always #(posedge Clk) begin
a <= 1'b0;
end
With a hardware description language a good approach is to consider what hardware we want to imply and describe it in the language. The construct always #(posedge Clk) is used to imply flip-flops, that is the output changes once per clock cycle. In the question we have a changing value 3 times, from 1 clock edge I do not know what hardware you are trying to imply.
You can not provide an inline synthesizable delay. For always #(posedge clk) blocks to be synthesizable they should be able to execute in zero time. You need to introduce a state machine to keep state between clock edges. I think I have already provided a good example on how to do this in my previous answer. If the delay is to be programmable then see mcleod_ideafix's answer.
I am currently teaching myself Verilog and going through a few tutorials that I found and two things that kind of confuse me are how to specifically calculate how much time you need to delay after changing the inputs to a combinatorial circuit, and in what order items get executed in your code. I understand generally that real circuits have rise/fall delay times and that you want to delay your outputs so that your inputs generate a value before you calculate your outputs, but I want to know specifics.
So, here's an example:
module dflipflop (d,clk,reset,q);
input d, clk, reset;
output q;
reg q;
always # (posedge clk or posedge reset) begin
if (reset) begin
q <= 0;
else begin
q <= #2 d; //why did I need to delay this 2 time units?
end
end
end module
module main;
reg d, clk, rst;
wire q;
dflipflop dff(d,clk,rst,q);
inital begin
forever begin
clk = 0;
#5
clk = 1;
#5
clk = 0; //why do I need to reset the clk to 0 if this is a forever block and my first assignment is clk = 0 in the beginning?
end
end
initial begin
d=0; rst=1;
#4 //why #4? How did they calculate that?
d=1; rst=0;
#50
d=1; rst=1;
#20
d=0; rst=0;
end
end module
Some of my questions are embedded in comments in the code. However, my other confusion is with timing. In the beginning of the main module, I instantiate a dflipflop module called dff with my parameters that I defined in main above. Where in my code does it say: rebuild the module/recalculate the Q when I change the inputs in main? I don't see the link.
On your specific questions:
//why did I need to delay this 2 time units?
You don't. Adding a transport delay to the clock branch and not the reset branch makes little or no sense.
//why do I need to reset the clk to 0 if this is a forever block and my first assignment is clk = 0 in the beginning?
You don't; the model is flawed. Remove the first clk=0, or move it above the forever.
//why #4? How did they calculate that?
No idea - it's just an arbitrary delay in your stimulus generation. It doesn't matter, as long as it's 'long enough'.
General points:
You don't care about specifying delays when writing HDL code; this
is almost always a job for the tools. Your tools will work out real
silicon delays and back-annotate them into your code using sdf,
specify blocks, and so on. If you want details, look at the
simulation model output by your synth or place-and-route tools.
As long as you're careful about your use of blocking and non-blocking assignments then your code will 'work', even though you haven't explicitly put delays into it. 'Working' means that the outputs change in the correct order to preserve your required functionality.
I think you may be confused in your understanding of 'rise/fall delays' and 'delaying outputs'. In general, at the HDL level, you're never concerned with signal rise or fall times; everything happens at a threshold voltage. An input changes at time x, and dependent outputs change at some later time. This is a propagation delay. For clocked circuits, the prop delay will depend on whether the output goes to 0 or goes to 1, which leads to unfortunate terminology involving 'rise delay' or 'fall delay' (actually propagation delay to 1, or to 0). You don't "delay your outputs so that your inputs generate a value before you calculate your outputs". Except in exceptional circumstances, you calculate your outputs immediately, and then specify how long it takes the outputs to actually propagate to the pins of your model.
If your dflipflop module will be synthesized, there should not be a #2 delay. Sometimes people add these delays because they are simulating with a mix of different coding styles: behavioral and structural. Sometimes the structural code has delays which make your behavioral code behave incorrectly.
Perhaps this is what was intended:
inital begin
clk = 0;
forever begin
#5
clk = 1;
#5
clk = 0;
end
end
Perhaps the #4 was used to release the rst just before the 1st clk edge at time=5.
q <= #2 d; This is the clock-to-q delay. The number is most likely arbitrary, but it could be coming from characterization of a specif flip-flop design. Many designers put a small delay on the clock-to-q to make the looking a waveforms easier. Normally you want this number very small and almost always less then the clock period.
for your clock generator, the extra clock = 0 doesn't matter as long as there is a semicolon. Most likely this is the coding style designer liked to use. Both of the following are equivalent to your clock, just written differently:
always begin
clk = 0;
#5;
clk = 1;
#5;
end
// or
initial begin
clk = 0;
forever #5 clk = !clk;
end
The #4 is because the designer wanted the test to end the reset on the design before the first clock (# #5). This also gives all the following delays (which are multiples of the clock period of #10) and #1 setup time.
your dflipflip will only react if there is a posedge clk or posedge reset. if reset is high, then q will be assigned to 0. If reset and the positive edge of clk is detected, then d will be sampled and #2 latter assign the sampled value to q.
Here is a step buy step on what is happening:
initial begin
d=0; rst=1; /* simulation time #0, rst goes 1'bx->1'b1 (posedge) therefore q goes 1'bx->1'b0 */
#4
d=1; rst=0; /*
simulation time #4, rst goes low, sill no posedge clk therefore dflipflop does nothing
simulation time #5 first posedge clk therefore sample d (1)
simulation time #7 q is assigned to 1 (sampled d)
simulation time #15 posedge clk therefore sample d (1) again
simulation time #17 q is assigned to 1 (sampled d) again
... repeat pattern ...
simulation time #45 posedge clk therefore sample d (1) again
simulation time #47 q is assigned to 1 (sampled d) again */
#50
d=1; rst=1; /*
simulation time #54, rst goes high therefore assign q to 0
simulation time #55 posedge clk, rst==1 therefore assign q to 0
simulation time #65 posedge clk, rst==1 therefore assign q to 0 */
#20
d=0; rst=0; /*
simulation time #74, rst goes low therefore no change
simulation time #74, initial block ends */
end