I want to instantiate 3 instances of my counter module. However, Xilinx will only instantiate one counter for me, not the three. Does anyone know why this is? In the RTL schematic, the 2nd two counters are connected straight to ground in their block diagrams, i.e. no logic implemented for them. Are my local parameters declared correctly?
I would really really appreciate your help. I have been staring at this problem for several hours.
Thank you so much for your help. It is really appreciated.
//Top Level Module:
`timescale 1ns / 1ps
//Top Level Wrapper module
module topWrapper(input CCLK, input reset, output clk, output max_tick_Green, output max_tick_Red, output max_tick_Amber);
localparam
M_Green = 5;
M_Red = 3;
M_Amber = 2;
//Frequency scaling of CCLK
//clk is used in the traffic light module and is a scaled version of CCLK
//CCLK: Frequency = 50MHz, Period = 20ns
//clk = Frequency = 1Hz, Period = 1s
//clkscale (frequency scaling parameter) = 1s/20ns = 5x10^7
clock clockScalingModule (CCLK, 50000000, clk);
//Counter for green light
//In traffic light sequence, change from green to amber after 12 clock cycles = 120s = 2mins
counter #(.M(M_Green)) countGreen
(.clk(clk), .reset(reset), .state(1), .max_tick(max_tick_Green));
//Counter for red light
//In traffic light sequence, change from green to amber after 12 clock cycles = 120s = 2mins
counter #(.M(M_Red)) countRed
(.clk(clk), .reset(reset), .state(1), .max_tick(max_tick_Red));
//Counter for amber light
//In traffic light sequence, change from green to amber after 12 clock cycles = 120s = 2mins
counter #(.M(M_Amber)) countAmber
(.clk(clk), .reset(reset), .state(1), .max_tick(max_tick_Amber));
endmodule
//Counter module:
//Counter - modulo M counter - counts 0 to M-1, then wraps around
module counter
//Parameters
//M = number of clock cycles the counter counts = max value
#(parameter M = 6)
//I/O signals
(
input wire clk, reset, state,
output wire max_tick
);
//Local parameter
//N = number of bits in counter
//N = ceiling(log2(M)) - definition at end of module
localparam N = clog2(M);
//Internal signal declaration
reg [N-1:0] r_reg;
wire [N-1:0] r_next;
//Body
//Rgister update
always#(posedge clk, posedge reset)
//Restart counter if reset is High or state is Low
//State = Low if this counter's light is not currently on
//State = High if this counter's light is currently on
if(reset)
r_reg <= 0;
//Only increment counter if state is High
//Only one of red, green, amber states is high
else if(state)
r_reg <= r_next;
else
r_reg <= 0;
//Next-state logic
assign r_next = (r_reg == M) ? 0: r_reg + 1;
//Output logic
//Max tick = HI when maximum count value is reached
//Max tick = LO otherwise
assign max_tick = (r_reg == M) ? 1'b1 : 1'b0;
//Ceiling log2() function definition
function integer clog2;
input integer value;
begin
value = value-1;
for (clog2=0; value>0; clog2=clog2+1)
value = value>>1;
end
endfunction
endmodule
Your issue is in your counter module. Your clog2 function returns the number of bits needed to represent inputvalue-1. Thus, if inputvalue is exactly a power of two, you can't represent inputvalue with the returned length.
This is probably not very clear, so let's look at what happens for M_amber = 2. In this case, clog2 return 1, r_reg is range [0:0], but you need 2 bits to represent 2 = 2'b10. And you need to be able to represent 2, since you have the checks r_reg == M in your code. Said check will always fail, and Xilinx remove the logic and connects your logic to ground.
Normally, if you want to count N cycles in HDL, you count from 0 to N-1. Thus, your code will be fine if you replace r_reg == M for r_reg == M-1.
Related
This is my first post and my first attempt at using a PLD.
I have written some code to make a breathing LED with 7 set points. The code produces a pwm output according to the first set point. It then slowly increases/decreases the pwm towards the next set point (7 in total).
The code works but I think it can be done better as I need to put 16 instantiations of this into a Lattice 4256 CPLD (not possible with my code).
I am keen to learn how a professional Verilog programmer would tackle this.
Many thanks in advance for your support.
PWM Generation
module LED_breath (led, tmr_clk);
output reg led;
input tmr_clk;
reg [7:0] cnt;
reg [6:0] pwm_cnt;
reg [6:0] pwm_val;
reg [2:0] pat_cnt;
reg [9:0] delay_cnt;
reg [6:0] cur_pat;
reg [6:0] nxt_pat;
parameter pattern = {7'h00, 7'h00, 7'h00, 7'h00, 7'h00, 7'h00, 7'h00, 7'h00};
always #(posedge tmr_clk)
begin
pwm_cnt = cnt[7] ? ~cnt[6:0] : cnt[6:0]; //Generate triangle wave
if(pwm_cnt > pwm_val) //Generate pwm
led <= 1'b0;
if(pwm_cnt < pwm_val)
led <= 1'b1;
cnt = cnt + 1;
end
always #(posedge tmr_clk) //breathing pattern
begin
if(!delay_cnt) //Add delay
begin
cur_pat <= ((pattern >> (7*pat_cnt)) & 7'b1111111); //Find correct pattern No. from parameter list
if((pat_cnt+1) == 8) //Check for last pattern - overflow, set to 0
nxt_pat <= (pattern & 7'b1111111);
else
nxt_pat <= ((pattern >> (7*(pat_cnt+1))) & 7'b1111111);
if(pwm_val == nxt_pat) //If pwm is at max or min increment count to get next pattern
pat_cnt <= pat_cnt + 1;
if(cur_pat <= nxt_pat) //Current pattern < next pattern, count up
pwm_val <= pwm_val + 1;
if(cur_pat >= nxt_pat) //Current pattern < next pattern, count down
pwm_val <= pwm_val - 1;
end
delay_cnt <= delay_cnt + 1;
end
endmodule
module top (led_0, led_1, led_2, led_3);
output led_0;
output led_1;
output led_2;
output led_3;
defparam I1.TIMER_DIV = "128";
OSCTIMER I1 (.DYNOSCDIS(1'b0), .TIMERRES(1'b0), .OSCOUT(osc_clk), .TIMEROUT(tmr_clk));
LED_breath #(.pattern({7'h20, 7'h70, 7'h50, 7'h70, 7'h40, 7'h10, 7'h60, 7'h10})) led_A(
.led (led_0),
.tmr_clk (tmr_clk)
);
LED_breath #(.pattern({7'h70, 7'h10, 7'h30, 7'h20, 7'h60, 7'h40, 7'h70, 7'h10})) led_B(
.led (led_1),
.tmr_clk (tmr_clk)
);
LED_breath #(.pattern({7'h10, 7'h30, 7'h10, 7'h18, 7'h40, 7'h50, 7'h30, 7'h60})) led_C(
.led (led_2),
.tmr_clk (tmr_clk)
);
LED_breath #(.pattern({7'h50, 7'h70, 7'h40, 7'h50, 7'h40, 7'h70, 7'h60, 7'h70})) led_D(
.led (led_3),
.tmr_clk (tmr_clk)
);
endmodule
Can you explain a bit what you are trying to achieve in this always block ?
always #(posedge tmr_clk)
I think you're using a fixed frequency and changing duty cycle to get desired breathing effect.
1) Is my thinking correct ?
2) If yes, how do you decide when to change the pattern ?
I want to implement a reciprical block on Verilog that will later be synthesized on an FPGA. The input should be a signed 32 bit wordlength with a 16 bit fraction length. The output should have the same format.
Example
input : x ---> output ---> 1/x
I have solved the problem using the inbuilt IP core divider. I'm wondering if there is an elegant/altenative way of solving this by for example by bit shifting or 2's complement with some xor grinds.
I have used the IP core to implement the inverse as it says in the manual but for some reason that i don't really understand the result is wrong and it needs to be shifted to the left by 1. For example; Reciprical of 1 gives 0.5 . Reciprical of 2 gives 1.
Below is a section from the manual and my testbench code
Test bench
module reciprical_tb;
// Inputs
reg clk;
reg [1:0] dividend;
reg [31:0] divisor;
// Outputs
wire rfd;
wire [1:0] quotient;
wire [31:0] fractional;
// Instantiate the Unit Under Test (UUT)
reciprical uut (
.rfd(rfd),
.clk(clk),
.dividend(dividend),
.quotient(quotient),
.divisor(divisor),
.fractional(fractional)
);
// clock
always begin
#5 clk = ~clk;
end
initial begin
// Initialize Inputs
clk = 0;
dividend = 2'b1; // 1
divisor = 2**16;; // = 1 when fraction length is 16bit
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here :: Inverse of 2 should give 0.5
//$display("inv(%g) => %g || inv = %b",$itor(divisor)*2.0**-16, $itor(fractional)*2.0**-16, fractional); //gives zero
$monitor("inv(%d) => q = %d || inv = %b", divisor>>>16,fractional>>>16, fractional); //gives a wrong answer by a factor of 2
// Using the monitor i get inv(1) = 0.5 instead of 1.
#100;
end
endmodule
Manual section (page 4):
...
The divider can be used to implement the reciprocal of X; that is the 1/X function. To do this, the
dividend bit width is set to 2 and fractional mode is selected. The dividend input is then tied to 01 for
both unsigned or signed operation, and the X value is provided via the divisor input.
Ip Core used
Trying to debug part of the question:
can you try :
// Wait 10 clock cycles
repeat (10) begin
#(posedge clk);
end
// Add stimulus here :: Inverse of 2 should give 0.5
$display("dsiplay inv(%g) => %g || inv = %b",$itor(divisor)*2.0**-16, $itor(fractional)*2.0**-16, fractional); //gives zero
$monitor("inv(%d) => q = %d || inv = %b", divisor>>>16,fractional>>>16, fractional); //gives a wrong answer by a factor of 2
// Using the monitor i get inv(1) = 0.5 instead of 1.
// Wait 10 clock cycles
repeat (10) begin
#(posedge clk);
end
$display("dsiplay inv(%g) => %g || inv = %b",$itor(divisor)*2.0**-16, $itor(fractional)*2.0**-16, fractional);
//End simulation
$finish();
As monitor is only issued once, it might be after 200ns that it is actually firing and outputting the updated value.
IP cores are normally pretty efficient, but they will use fabric multipliers and a reasonable amount of logic. Depending on the accuracy that you need it could also be done with a look-up-table stored in block RAM. A RAM that used the raw input as the address would be massively too big for a device. But you can store a reciprocal curve and pre-scale the input and apply shifts at the output. You can reduce the ram usage further by linearly interpolating between two points on the curve.
It depends on what resources you have and what accuracy you need.
I am working with an Altera DE2 development board and I want to read an input in on the switches. This is stored in registers. Based on a counter these registers are incremented. The registers are then supposed to be output to the Seven Segment Displays thought a B2D converter. But I can not pass a register to a function.
wire [26:0] Q,Q2,Q3,Q4;
wire [3:0] one,two,three,four;
reg SecInc,MinInc,HrInc;
reg [3:0] M1,M2,H1,H2;
assign one = SW[3:0];
assign two = SW[7:4];
assign three = SW[11:8];
assign four = SW[15:12];
always begin
M1 = SW[3:0];
M2 = SW[7:4];
H1 = SW[11:8];
H2 = SW[15:12];
end
This is how I get and store the inputs. They come from the switches which we use as a binary representation on Hours and Minutes.
Based on a counter we increment a minute or an hour register.
//increment seconds from 0 to 60
counter seconds (SecInc,KEY[0],Q2);
defparam seconds.n = 8;
defparam seconds.mod = 60;
always # (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
M1 <= M1 + 1'b1;
if(M1 >= 9) begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
We want to display the result on the SSD's.
hex(M1,HEX4);
hex(M2,HEX5);
hex(H1,HEX6);
hex(H2,HEX7);
Here in lies the problem. This is not allowed in verilog. I need a way to send my registers to a function which displays numbers from 0 to 9 using some B2D conversion.
I will say I have never had a formal intro to verilog before and I have tried all I can think to do. I even tried to make a new module in which I would pass one,two,three,four and have the module increment them, like it does with Q2 for the counter I have shown. Any suggestions or help is greatly appreciated!
As requested here is the hex module:
module hex(BIN, SSD);
input [15:0] BIN;
output reg [0:6] SSD;
always begin
case(BIN)
0:SSD=7'b0000001;
1:SSD=7'b1001111;
2:SSD=7'b0010010;
3:SSD=7'b0000110;
4:SSD=7'b1001100;
5:SSD=7'b0100100;
6:SSD=7'b0100000;
7:SSD=7'b0001111;
8:SSD=7'b0000000;
9:SSD=7'b0001100;
endcase
end
endmodule
Thank you in advance!
Your hex module is not a function, it is a module and therefore must be instantiated with an instance name like this:
hex digit0(.BIN(M1), .SSD(HEX4));
hex digit1(.BIN(M2), .SSD(HEX5));
hex digit2(.BIN(H1), .SSD(HEX6));
hex digit3(.BIN(H2), .SSD(HEX7));
In addition to nguthrie being correct, that you need to instantiate your hex converter as a module, you drive M1 from a race condition in your always block. Non-blocking assignments will evaluate simultaneously within a block (or essentially simultaneously). This is not a program, where things happen in order. What might work better is:
always # (negedge CLOCK_50) begin
if (Q2 >= 60) begin
MinInc = 1;
if (M1 < 9) begin
M1 <= M1 + 1'b1;
end else begin
M1 <= 0;
M2 <= M2 + 1'b1;
end
end else begin
MinInc = 0;
end
end
You will also potentially get unexpected results from your blocking assignments to MinInc, but since I don't see where this is read it's hard to know what will happen.
Read up on blocking (=) vs non-blocking (<=) assignments in Verilog. It's one of the trickiest concepts of the language, and misuse of the two operations is the cause of 90% of the most dastardly bugs I've ever seen.
EDIT: In re-reading your question, it seems that you're trying to drive M1-4 from at least three places. You really can't have a continuous always begin block and a clocked (always # (negedge clock) begin) driving the same register. This will send your compiler into a tantrum.
I am writing code for an entity that takes in RGB values, averages them, then outputs the altered data.
My code looks like this:
module RGBAVG (
input clk,
input rst_n,
input [9:0] iVGA_R,
input [9:0] iVGA_G,
input [9:0] iVGA_B,
output reg [9:0] oVGA_R,
output reg [9:0] oVGA_G,
output reg [9:0] oVGA_B
);
integer avg;
integer count;
integer sum;
initial begin
count = 0;
sum = 0;
avg = 0;
end
always#(posedge clk or negedge rst_n) begin
if (!rst_n) begin //reset
sum = 0;
count = 0;
oVGA_R <= {10{1'b0}};
oVGA_G <= {10{1'b0}};
oVGA_B <= {10{1'b0}};
end
else begin //get RGB values from pixel, prepare for next avg evaluation
count = (count + 1)%307200; //640*480 = 307200
sum = sum + (iVGA_R + iVGA_G + iVGA_B)/3;
if (count == 0) begin
avg = sum/307200; //update avg
sum = 0;
end
oVGA_R <= avg;
oVGA_G <= avg;
oVGA_B <= avg;
end
end
endmodule
However, when I upload the code, all I get is a black screen. What am I doing wrong?
When you say 'compile', do you mean synthesize for a specific target? Are you trying to simulate this, or load it onto an FPGA?
I cannot say exactly what that error means, though I might make a suggestions that may make it go away.
Your logic is somewhat strange to me and probably not synthesizeable. You have an asynchronous reset to your always block, and you're saying that:
Anytime I assert this asynchronous reset, increment the value of count and sum
This kind of construct does not really exist in typical hardware, your asynchronous reset should do only one thing, which is to reset the state of all your flops. Therefore I recommend to move all this:
count = (count + 1)%307200;
sum = sum + (iVGA_R + iVGA_G + iVGA_B)/3;
if (count == 0) begin
avg = sum/307200;
sum = 0;
end
into the else clause so that it doesn't try to write new register values on asynchronous reset. I suspect that this has something to do with your error. You probably want to reset the count and sum as well on reset, is my guess.
I want to have a 2 sec counter in my for loop such that there is a gap of 2 seconds between every iteration.I am trying to have a shifting LEDR Display
Code:
parameter n =10;
integer i;
always#(*)
begin
for(i=0;i<n;i=i+1)
begin
LEDR[i]=1'b1;
//2 second counter here
end
end
What is your desired functionality? I assume: shifting which LED is on every 2 seconds, keeping all the other LEDs off? "Sliding LED"...
Also, I am assuming your target is an FPGA-type board.
There is no free "wait for X time" in the FPGA world. The key to what you are trying to do it counting clock cycles. You need to know the clock frequency of the clock that you are using for this block. Once you know that, then you can calculate how many clock rising edges you need to count before "an action" needs to be taken.
I recommend two processes. In one, you will watch rising edge of clock, and run a counter of sufficient size, such that it will roll over once every two seconds. Every time your counter is 0, then you set a "flag" for one clock cycle.
The other process will simply watch for the "flag" to occur. When the flag occurs, you shift which LED is turned on, and turn all other LEDs off.
I think this module implements what Josh was describing. This module will create two registers, a counter register (counter_reg) and a shift register (leds_reg). The counter register will increment once per clock cycle until it rolls over. When it rolls over, the "tick" variable will be equal to 1. When this happens, the shift register will rotate by one position to the left.
module led_rotate_2s (
input wire clk,
output wire [N-1:0] leds,
);
parameter N=10; // depends on how many LEDs are on your board
parameter WIDTH=<some integer>; // depends on your clock frequency
localparam TOP=<some integer>; // depends on your clock frequency
reg [WIDTH-1:0] counter_reg = 0, counter_next;
reg [N-1:0] leds_reg = {{N-1{1'b0}}, 1'b1}, leds_next;
wire tick = (counter_reg == 0);
assign leds = leds_reg;
always #* begin : combinational_logic
counter_next = counter_reg + 1'b1;
if (counter_next >= TOP)
counter_next = 0;
leds_next = leds_reg;
if (tick)
leds_next = {leds_reg[N-2:0], leds_reg[N-1]}; // shift register
end
always #(posedge clk) begin : sequential_logic
counter_reg <= counter_next;
leds_reg <= leds_next;
end
endmodule