I'm trying to get a triangle waveform, but my code doesn't work! I think the "if conditions" are organised wrong but I can't find the mistake My wave goes up like it should be and it falls down by 90° after achieving the top
module pila(clk,res,out2);
input clk,res;
output [0:7]out2;
reg [0:7]out2;
always #(posedge clk)
begin
if (res)
begin
if(out2<=8'b11111111)
out2=out2+1;
else if(out2>=8'b00000000)
out2=out2-1;
else out2=8'b00000000;
end
else out2=8'b00000000;
end
endmodule
module testbench;
reg clk,res;
wire [0:7]out2;
pila Sevo(clk,res,out2);
always #2 clk=~clk;
initial
begin
clk=0;res=0;
#2 res=1;
end
initial #5000 $finish;
endmodule
You need some signal to indicate which direction you are currently counting. Also use the non-blocking assignment operator <= rather than the blocking assignment operator =.
module pila(clk,res,out2);
input clk,res;
output [0:7]out2;
reg [0:7]out2 = 8'h00;
reg count_down = 1'b0;
always #(posedge clk)
begin
if (count_down == 1'b0)
begin
if (out2==8'b11111111) // check for top of count
begin
count_down <= 1'b1;
out2<=out2-1;
end
else
out2<=out2+1;
end
else
begin
if(out2==8'b00000000) // check for bottom of count
begin
count_down <= 1'b0;
out2<=out2+1;
end
else
out2<=out2-1;
end
end
endmodule
The if(out2<=8'b11111111) condition is always evaluating to true. This is because out2 range is 0 to 255. Try adding another flop to control the direction, for example downup where 1 means decrement and 0 means increment.
if (out2 == 8'h00) begin
downup <= 1'b0; // up
out2 <= 8'h01;
end
else if (out2 == 8'hFF) begin
downup <= 1'b1; // down
out2 <= 8'hFE;
end
else if (downup) begin // down
out2 <= out2 - 1;
end
else begin // up
out2 <= out2 + 1;
end
Other issues:
Use non-blocking assignment (<=) for synchronous logic.
Typically reset (and set) conditions are declared before synchronous logic assignment
Little-Endian ([7:0]) is more commonly used for packed arrays (previously known as vectors) then Big-Endian ([0:7]), http://en.wikipedia.org/wiki/Endianness
Working example: http://www.edaplayground.com/x/4_b
Related
I will get straight to the point. I have a simple counter that is trying to
mimic how a clock works pretty much. I have a module called counter60sec and another one called counter12hr
counter12hr
module counter12hr(reset, hourInc, overflowOut, hrCounter);
input reset;
input hourInc;
output overflowOut;
output [3:0] hrCounter;
reg overflowOut;
reg [3:0] hrCounter; //0'b1101 == 13 hours
//Initialize counter
initial begin
overflowOut = 1'b0;
hrCounter = 4'b0; //once hour reaches 12:59:59, it is supposed to go back to zero
end
//Everytime hrInc is one, increment hrCounter
always#(negedge reset or posedge hourInc) begin
overflowOut = 1'b0;
if(reset == 1'b0) begin
overflowOut = 1'b0;
hrCounter = 4'b0;
end
else begin
if (hourInc == 1'b1) begin
hrCounter = hrCounter + 1'b1;
end
end
end
always#(negedge hrCounter) begin
if (hrCounter == 4'b1100) begin
overflowOut = 1'b1;
hrCounter = 4'b0;
end
end
endmodule
counter60sec
module counter60sec(reset, secInc, minOut, secCounter);
input reset;
input secInc;
output minOut;
output [5:0] secCounter;
reg [5:0] secCounter; //0'b111100 == 60 seconds.
reg minOut;
//Initialize counter
initial begin
minOut = 1'b0;
secCounter = 6'b0;
end
//Everytime secInc is one, increment secCounter
always#(posedge secInc or negedge reset) begin
minOut = 1'b0;
if(reset == 1'b0) begin
minOut = 1'b0;
secCounter = 6'b0;
end
else begin
if (secInc == 1'b1) begin
secCounter = secCounter + 1'b1;
end
end
end
//output minOut to 1 to signal minute increase when secCounter hits 111100 in binary
always#(negedge secCounter) begin
if(secCounter == 6'b111100) begin
minOut = 1'b1;
secCounter = 6'b0;
end
end
endmodule
I have test bench set up for both. The counter60sec one works fine (Where when secCounter is at value of 60, the minOut becomes 1). The counter12hr follows the same concept, but the value of overflowOut never becomes 1.
For my hrCounter conditional statement in counter12hr.v, I have tried both 4'b1101 and 4'b1100 and neither of them worked. (Trying to get the overflowOut to become one when the hrCounter hits 13)
I've spent hours on this, taking break to relax my eyes etc. I still can't see where I am going wrong. Any help would be appreciated
you have a few issues. The main one is that you have a multiple-driven register in both cases:
always#(negedge reset or posedge hourInc) begin
overflowOut = 1'b0;
...
always#(negedge hrCounter) begin
if (hrCounter == 4'b1100) begin
overflowOut = 1'b1;
the overflowOut is driven from 2 different alsways blocks. Same as minOut in the second counter. The order in which those statements are executed is undefined and the resulting value would depend on the order.
You need to restructure your program in such a way that the registers are assigned in a single always block only.
Secondly, i think, that you have a logic bug, assigning your overflow to '0' in the first statement of the first block (same as in the second one).
Thirdly, you should have uset non-blocking assighments '<=' in finlal assignments to the registers.
something like the following should work.
always#(negedge reset or posedge hourInc) begin
if(reset == 1'b0) begin
hrCounter <= 4'b0;
overflowOut <= 1'b0;
end
else begin
if (hrCounter == 4'b1100) begin
overflowOut <= 1'b1;
hrCounter <= 4'b0;
end
else
hrCounter <= hrCounter + 1'b1;
overflowOut <= 1'b0;
end
end
end
Your code is wrong in so many ways...
Most likely it does not work because of:
#(negedge hrCounter)
You are using a vector but #... works with bits. So it will look at the LS bit only.
As to your code:first and most start using a clock. Do not use posedge and negedge of your signals to drive the other signals.
You use:
always#(posedge secInc ...
...
if (secInc == 1'b1)
Remove the 'if'. you have that condition already in your always statement. (But the signal should not be the 'always' anyway, it should be your clock)
Remove the 'initial' sections You have a reset which defines the start condition.
If you have an active low reset reflect that in the name. Call it reset_n or n_reset anything but 'reset' which is per convention a positive reset signal.
If your drive ANYTHING from an edge, be it from a clock or from other signals, use non-blocking assignments "<="
Do not use your generated signal edges to generate other signals. As mentioned use a clock for everything an in the clocking section use an if. Also do not drive signals from different 'always'. You can never know in which order they are executed and then you have a race condition. Thus the clear and the increment are all in one always block:
if (secCounter == 6'b111100) begin
minOut <= 1'b1;
secCounter <= 6'b0;
end
else
secCounter <= secCounter + 6'b000001;
Because of the timing aspect you now have to go to 59 not 60. Which is as you should expect as digital clocks and watches run from 00 to 59, not 00 to 60. You are allowed to use decimal numbers which will, again, make the code more readable: 6'd59, 4'd11
wanted to implement PWM sequence using top-level verilog 2005 module:
module PWM_ENHANCER (
input clk,
input rst,
input sent,
//input
input [7:0] BUF, //BUFFER - The PWM reads from it only when 'sent' signal is received, and the current run is done.
//output
output reg PWM_WAIT,
output reg PWM_OUT
);
reg [7:0] SAMPLE;
reg [7:0] counter;
reg WORK;
always#(posedge clk or negedge rst)
begin
if( !rst )
begin
WORK <= 1'b0; //When receiving a reset, everything zeroes.
counter <= 8'b0;
PWM_WAIT <= 1'b1;
SAMPLE <= 8'b0;
PWM_OUT <= 1'b0;
end
else if (sent == 1 && WORK == 0)
begin //If the pwm was OFF, and i received sign from the array, i start running PWM.
SAMPLE <= BUF;
WORK <= 1'b1;
PWM_WAIT <= 1'b0;
end
else if(WORK == 1)
begin //The running block - sending '0' and '1' as needed.
if ( (counter <= SAMPLE) && (SAMPLE != 0) )
begin
PWM_OUT <= 1'b1;
counter = counter + 1'b1;
end
else if ( counter > SAMPLE )
begin
if ( counter == 8'b11111111 )
begin
counter <= 8'b0;
WORK <= 1'b0;
end
else
begin
counter = counter + 1'b1;
PWM_OUT <= 1'b0;
end
end;
if(counter == 200)
begin // 50 cycles before the end, PWM sends acknowledge for the array to send the next sample.
PWM_WAIT <= 1'b1;
end
end
else
begin
; // if NOT receiving 'sent' from the array - the PWM does nothing.
end
end
endmodule
received error when compiling:
"Internally generated reset in top design unit 'PWM_ENHANCER' is not allowed."
How can i have a reset included in the #always statement?
Two possibility (both synthesis related):
Your synthesizer needs additional hand-holding for the asynchronous reset
if(!rst) begin
WORK <= 1'b0;
counter <= 8'b0;
PWM_WAIT <= 1'b1;
SAMPLE <= 8'b0;
PWM_OUT <= 1'b0;
end
else begin
// other logic in here
end
Your standard cell library lacks flops with asynchronous reset/preset. FPGA's tend to have a limited number of flops with asynchronous reset/preset. Some FPGA do not have any. If this is the case the simplest thing that can be done is change the for asynchronous reset to synchronous reset by changing the top of your always block to always#(posedge clk) (omitting the or negedge rst).
If you are on FPGA, then you may want to add an initial block to initialize the defaults of the registers.
I'm trying to implement simple JK Flipflop in Verilog (Modelsim). But I'm getting the following error
The generate if condition must be a constant expression.
Here is the code which I'm using
module jkfflop(J,K,clk,Q);
input J,K,clk;
output Q;
if(J==0 & K==1)
begin
assign Q = 0;
end
else if(J==1 & K==0)
begin
assign Q = 1;
end
else if(J==1 & K==1)
begin
assign Q = ~Q;
end
endmodule
Can someone help me
In Verilog RTL there is a formula or patten used to imply a flip-flop. for a Positive edge triggered flip-flop it is always #(posedge clock) for negative edge triggered flip-flops it would be always #(negedge clock).
An Example of positive edge triggered block.
reg [7:0] a;
always #(posedge clock) begin
a <= b;
end
Normally you want a reset as well, a Synchronous reset would be:
reg [7:0] a;
always #(posedge clock) begin
if ( reset == 1'b1 ) begin
a <= 'b0;
end
else begin
a <= b;
end
end
It is more common is ASIC design to require an active low Asynchronous :
reg [7:0] a;
always #(posedge clock, negedge reset_n) begin
if ( reset_n == 1'b0 ) begin
a <= 'b0;
end
else begin
a <= b;
end
end
Note that the asynchronous reset has reset in the sensitivity list this makes the block respond to changes in the signal.
The way you have used (reused) assign is incorrect.
Using the above info your module would become:
module jkfflop(
input J,
input K,
input clk,
output Q );
always #(posedge clk) begin
if(J==1'b0 && K==1'b1) begin
Q <= 'b0;
end
else if(J==1'b1 && K==1'b0) begin
Q <= 1'b1;
end
else if(J==1'b1 & K==1'b1) begin
Q <= ~Q;
end
end
endmodule
But could be written with a case statement:
always #(posedge clk) begin
case({J,K})
2'b0_0 : Q <= Q ;
2'b0_1 : Q <= 1'b0;
2'b1_0 : Q <= 1'b1;
2'b1_1 : Q <= ~Q ;
endcase
end
I am trying to pass an integer value to a module, but the IF statement does not work with the parameter. It throws the following error. I am new to Verilog so I have no idea how to make this work.
Error (10200): Verilog HDL Conditional Statement error at clock_divider.v(17):
cannot match operand(s) in the condition to the corresponding edges in the enclosing
event control of the always construct
clock_divider.v module
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always # (posedge clk or negedge rst_n)
begin
if(clockHandler == 0)
begin div_helper = DIV_CONST;
end
else
begin div_helper = DIV_CONST_faster;
end
if (!rst_n)
begin div <= 0;
en <= 0;
end
else
begin
if (div == div_helper)
begin div <= 0;
en <= 1;
end
else
begin div <= div + 1;
en <= 0;
end
end
end
always # (posedge clk or negedge rst_n)
begin
if (!rst_n)
begin
clk_o <= 1'b0;
end
else if (en)
clk_o <= ~clk_o;
end
endmodule
main.v module
reg clockHandler = 1;
// 7-seg display mux
always # (*)
begin
case (SW[2:0])
3'b000: hexdata <= 16'h0188;
3'b001: hexdata <= register_A ;
3'b010: hexdata <= program_counter ;
3'b011: hexdata <= instruction_register ;
3'b100: hexdata <= memory_data_register_out ;
3'b111: hexdata <= out;
default: hexdata <= 16'h0188;
endcase
if(SW[8] == 1)
begin
clockHandler = 1;
end
else
begin
clockHandler = 0;
end
end
HexDigit d0(HEX0,hexdata[3:0]);
HexDigit d1(HEX1,hexdata[7:4]);
HexDigit d2(HEX2,hexdata[11:8]);
HexDigit d3(HEX3,hexdata[15:12]);
clock_divider clk1Hzfrom50MHz (
clockHandler,
CLOCK_50,
KEY[3],
clk_1Hz
);
It's my understanding that the first statement in a verilog always block must be the if(reset) term if you're using an asynchronous reset.
So the flop construct should always look like this:
always # (posedge clk or negedge rst_n) begin
if(~rst_n) begin
...reset statements...
end else begin
...all other statements...
end
end
So for your case you should move the if(clockHandler==0) block inside the else statement, because it is not relevant to the reset execution. Even better would be to move it into a separate combinational always block, since mixing blocking and nonblocking statements inside an always block is generally not a good idea unless you really know what you're doing. I think it is fine in your case though.
To add to Tim's answer - the original code (around line 17, anyway) is valid Verilog.
What it's saying is "whenever there's a rising edge on clk or a falling edge on rst_n, check clockHandler and do something" (by the way, get rid of the begin/ends; they're redundant and verbose). The problem comes when you want to implement this in real hardware, so the error message is presumably from a synthesiser, which needs more than valid Verilog. The synth suspects that it has to build a synchronous element of some sort, but it can't (or won't, to be precise) handle the case where clockHandler is examined on an edge of both clk and rst_n. Follow the rules for synthesis templates, and you won't get this problem.
is this a compilation error or synthesis error? i used the same code to see if it compiles fine, and i din get errors.. Also, it is recommended to use "<=" inside synchronous blocks rather than "="
You're using the same flop construct for two different things. Linearly in code this causes a slipping of states. I always place everything within one construct if the states rely on that clock or that reset, otherwise you require extra steps to make sure more than one signal isn't trying to change your state.
You also don't need the begin/end when it comes to the flop construct, Verilog knows how to handle that for you. I believe Verilog is okay with it though, but I generally don't do that. You also don't have to use it when using a single statement within a block.
So your first module would look like this (if I missed a block somewhere just let me know):
clock_divider.v module (edited)
module clock_divider (clockHandler, clk, rst_n, clk_o);
parameter DIV_CONST = 10000000 ; // 1 second
parameter DIV_CONST_faster = 10000000 / 5;
input clockHandler;
input clk;
input rst_n;
output reg clk_o;
reg [31:0] div;
reg en;
integer div_helper = 0;
always # (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div <= 0;
en <= 0;
clk_o <= 1'b0;
end
else if(en)
begin
clk_o <= ~ clk_o;
if(clockHandler == 0)
begin
div_helper = DIV_CONST;
end
else
begin
div_helper = DIV_CONST_faster;
end
else
begin
if (div == div_helper)
begin
div <= 0;
en <= 1;
end
end
else
begin
div <= div + 1;
en <= 0;
end
end
end
end module
If that clk_o isn't meant to be handled at the same time those other operations take place, then you can separate everything else with a general 'else' statement. Just be sure to nest that second construct as an if-statement to check your state.
And also remember to add always # (posedge clk or negedge rst_n) to your main.v module as Tim mentioned.
I wrote a behavioral program for booth multiplier(radix 2) using state machine concept. I am getting the the results properly during the program simulation using modelsim, but when I port it to fpga (spartan 3) the results are not as expected.
Where have I gone wrong?
module booth_using_statemachine(Mul_A,Mul_B,Mul_Result,clk,reset);
input Mul_A,Mul_B,clk,reset;
output Mul_Result;
wire [7:0] Mul_A,Mul_B;
reg [7:0] Mul_Result;
reg [15:0] R_B;
reg [7:0] R_A;
reg prev;
reg [1:0] state;
reg [3:0] count;
parameter start=1 ,add=2 ,shift=3;
always #(state)
begin
case(state)
start:
begin
R_A <= Mul_A;
R_B <= {8'b00000000,Mul_B};
prev <= 1'b0;
count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add:
begin
case({R_B[0],prev})
2'b00:
begin
prev <= 1'b0;
end
2'b01:
begin
R_B[15:8] <= R_B[15:8] + R_A;
prev <= 1'b0;
end
2'b10:
begin
R_B[15:8] <= R_B[15:8] - R_A;
prev <= 1'b1;
end
2'b11:
begin
prev <=1'b1;
end
endcase
end
shift:
begin
R_B <= {R_B[15],R_B[15:1]};
count <= count + 1;
end
endcase
end
always #(posedge clk or posedge reset)
begin
if(reset==1)
state <= start;
else
begin
case(state)
start:
state <= add;
add:
state <= shift;
shift:
begin
if(count>7)
state <= start;
else
state <=add;
end
endcase
end
end
endmodule
You have an incomplete sensitivity list in your combinational always block. Change:
always #(state)
to:
always #*
This may be synthesizing latches.
Use blocking assignments in your combinational always block. Change <= to =.
Good synthesis and linting tools should warn you about these constructs.
Follow the following checklist if something does work in the simulation but not in reality:
Did you have initialized every register? (yes)
Do you use 2 registers for one working variable that you transfer after each clock (no)
(use for state 2 signals/wires, for example state and state_next and transfer after each clock state_next to state)
A Example for the second point is here, you need the next stage logic, the current state logic and the output logic.
For more informations about how to proper code a FSM for an FPGA see here (go to HDL Coding Techniques -> Basic HDL Coding Techniques)
You've got various problems here.
Your sensitivity list for the first always block is incomplete. You're only looking at state, but there's numerous other signals which need to be in there. If your tools support it, use always #*, which automatically generates the sensitivity list. Change this and your code will start to simulate like it's running on the FPGA.
This is hiding the other problems with the code because it's causing signals to update at the wrong time. You've managed to get your code to work in the simulator, but it's based on a lie. The lie is that R_A, R_B, prev, count & Mul_Result are only dependent on changes in state, but there's more signals which are inputs to that logic.
You've fallen into the trap that the Verilog keyword reg creates registers. It doesn't. I know it's silly, but that's the way it is. What reg means is that it's a variable that can be assigned to from a procedural block. wires can't be assigned to inside a procedural block.
A register is created when you assign something within a clocked procedural block (see footnote), like your state variable. R_A, R_B, prev and count all appear to be holding values across cycles, so need to be registers. I'd change the code like this:
First I'd create a set of next_* variables. These will contain the value we want in each register next clock.
reg [15:0] next_R_B;
reg [7:0] next_R_A;
reg next_prev;
reg [3:0] next_count;
Then I'd change the clocked process to use these:
always #(posedge clk or posedge reset) begin
if(reset==1) begin
state <= start;
R_A <= '0;
R_B <= '0;
prev <= '0;
count <= '0;
end else begin
R_A <= next_R_A;
R_B <= next_R_B;
prev <= next_prev;
count <= next_count;
case (state)
.....
Then finally change the first process to assign to the next_* variables:
always #* begin
next_R_A <= R_A;
next_R_B <= R_B;
next_prev <= prev;
next_count <= count;
case(state)
start: begin
next_R_A <= Mul_A;
next_R_B <= {8'b00000000,Mul_B};
next_prev <= 1'b0;
next_count <= 3'b000;
Mul_Result <= R_B[7:0];
end
add: begin
case({R_B[0],prev})
2'b00: begin
next_prev <= 1'b0;
end
.....
Note:
All registers now have a reset
The next_ value for any register defaults to it's previous value.
next_ values are never read, except for the clocked process
non-next_ values are never written, except in the clocked process.
I also suspect you want Mul_Result to be a wire and have it assign Mul_Result = R_B[7:0]; rather than it being another register that's only updated in the start state, but I'm not sure what you're going for there.
A register is normally a reg, but a reg doesn't have to be a register.