Reputation: 1
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
Upvotes: 0
Views: 359
Reputation: 3388
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
.
Upvotes: 1