Unexpected behaviour using the ternary operator (Verilog) - verilog

In the following Verilog module, I'd like to understand why the blocking assignment using concatenation doesn't give the same result as the 2 commented out blocking assignments.
When I run the program on the FPGA, it gives the expected result with the 2 blocking assignments (the leds blink), but not with the blocking assignment using concatenation (the leds stay off).
Bonus points for answers pointing to the Verilog specification explaining what is at play here!
/* Every second, the set of leds that are lit will change */
module blinky(
input clk,
output [3:0] led
);
reg [3:0] count = 0;
reg [27:0] i = 0;
localparam [27:0] nTicksPerSecond = 100000000;
assign led = {count[3],count[2],count[1],count[0]};
always # (posedge(clk)) begin
// This works:
//count = i==nTicksPerSecond ? (count + 1) : count;
//i = i==nTicksPerSecond ? 0 : i+1;
// But this doesn't:
{count,i} = i==nTicksPerSecond ?
{count+1, 28'b0 } :
{count , i+1};
end
endmodule
PS: I use Vivado 2018.2

The reason is because the widths of count+1 and i+1 are both 32 bits. An unsized number is 32 bits wide (1800-2017 LRM section 5.7.1) and the width of the addition operator is the size of the largest operand (LRM section 11.6.1). To make your code work, add a proper size to your numeric literals
{count,i} = i==nTicksPerSecond ?
{count+4'd1, 28'b0 } :
{count , i+28'd1};
A simpler way to write this code is
always # (posedge clk)
if (i== nTicksPerSecond)
begin
count <= count + 1;
i <= 0;
end
else
begin
i <= i + 1;
end

Related

How can I prevent that DSP blocks are synthesized away if they are not connected to a top level output?

I am using an Intel Stratix 10 FPGA and Quartus Prime Pro 21.4 to develop a power test project.
I cannot figure out how keep Quartus from optimizing away my DSP blocks.
I want to use all 3000 DSP blocks in our FPGA so that I can see the max current draw of the DSP block. Of course, we can use the power estimator, but we require a real-world physical test.
I actually don't need the output from the DSP block. I only care that they are running and using FPGA resources.
I have instantiated the Intel fixed DSP core IP as a multiplier:
https://www.intel.com/content/www/us/en/docs/programmable/683450/current/native-fixed-point-dsp-intel-stratix-51840.html
I am using a generate for loop to generate 3000 of these DSP IP blocks. My problem is that the DSP blocks are synthesized away unless I connect the output from each of the DSP blocks directly to a top level output. I only have ~1000 outputs available so this is not possible.
I thought I could just connect each output with a register array to catch the output. But it seems that if I don't actually use the output values or connect it outright to a top level output pin, then Quartus thinks we don't need it and optimizes it away.
The 2nd solution I tried is to use combinational logic:
top_output = DSP_out[0] || DSP_out[1] || DSP_out[2] || DSP_out[3]
this solution will generate 4 DSP blocks even though the generate loop runs 3000 times. I tried doing this in a loop, but it did not work. Is there a way to trick the system into synthesizing all the DSP blocks even if I don't connect the block to a top level output?
I seem to be able to access the output of the DSP block with no issues. For instance, I was able to turn on or off an LED based on the numbers I fed into a single multiplier.
Here is the full code:
`timescale 1ps/1ps
`default_nettype none
module power_test_design (
input wire clk_i,
output reg [0:0] outputa,
output reg [0:0] outputb
);
localparam NUM_DSP_BLOCKS = 3000;
genvar i;
wire reset;
integer k;
//input stimulus signals for the DSP
reg [17:0] ay_r;
reg [17:0] by_r;
reg [17:0] ax_r;
reg [17:0] bx_r;
//create wires and registers to hold outputs from multiplier
(* keep = "true" *) wire [36:0] resulta [NUM_DSP_BLOCKS-1:0];
(* keep = "true" *) reg [36:0] resulta_r [NUM_DSP_BLOCKS-1:0];
(* keep = "true" *) wire [36:0] resultb [NUM_DSP_BLOCKS-1:0];
(* keep = "true" *) reg [36:0] resultb_r [NUM_DSP_BLOCKS-1:0];
reg [2:0] ena_r;
// Stratix10 system reset
reset_release U_RESET (
.ninit_done (reset ) // output, width = 1, ninit_done.ninit_done
);
// DSP stimulus
always #(posedge clk_i) begin : DSP_SET_FF
if (reset)
begin
ay_r <= {18{1'b0}};
by_r <= {18{1'b0}};
ax_r <= {18{1'b0}};
bx_r <= {18{1'b0}};
ena_r <= {3{1'b0}};
end else
begin
ena_r <= 3'b001;
ay_r <= $unsigned(ay_r) + 1;
by_r <= $unsigned(by_r) + 1;
ax_r <= $unsigned(ax_r) + 2;
bx_r <= $unsigned(bx_r) + 3;
end
end
generate
for (i=0; i<NUM_DSP_BLOCKS; i=i+1) begin : GEN_DSPS
dsp_fixed U_DSP (
.ay (ay_r), // input, width = 18, ay.ay
.by (by_r), // input, width = 18, by.by
.ax (ax_r), // input, width = 18, ax.ax
.bx (bx_r), // input, width = 18, bx.bx
.resulta (resulta[i]), // output, width = 37, resulta.resulta
.resultb (resultb[i]), // output, width = 37, resultb.resultb
.clk0 (clk_i), // input, width = 1, clk0.clk
.clk1 (), // input, width = 1, clk1.clk
.clk2 (), // input, width = 1, clk2.clk
.ena (ena_r) // input, width = 3, ena.ena
);
//bring result to a register to assign output logic
assign resulta_r[i] = resulta[i];
assign resultb_r[i] = resultb[i];
end
endgenerate
//output logic -this code generates 6 DSP blocks....I need to generate all 3000
always #(posedge clk_i) begin : outputLogic
for (k=1; k<50; k=k+1)
begin
outputa = resulta_r[k] || resulta_r[k+1] || resulta_r[k+2];
outputb = resultb_r[k+3] || resultb_r[k+4] || resultb_r[k+5];
end
end
endmodule
`resetall
So far, I tried several ways to assign this output. first:
always #(resulta_r[0], resulta_r[1], resulta_r[2], resulta_r[3]) begin
if (resulta_r[0] == 4)
begin
outputa = 1;
end
else if (resulta_r[1] == 6)
begin
outputa = 1;
end
else if (resulta_r[2] == 6)
begin
outputa = 1;
end
else if (resulta_r[3] == 6)
begin
outputa = 1;
end
else
begin
outputa = 0;
end
end
With this code, DSP blocks are generated for each if statement. So, the next idea was
always #(posedge clk_i) begin : outputLogic
for (k=1; k<50; k=k+1)
begin
outputa = resulta_r[k] || resulta_r[k+1] || resulta_r[k+2];
outputb = resultb_r[k+3] || resultb_r[k+4] || resultb_r[k+5];
end
end
This works in a similar way. I get a DSP block generated for each result[k] in the combinational statement. But this only generates 6 DSP blocks in total when synthesizing. It only generates blocks based on how many DSP block outputs are in this combinational statement.
I solved this issue using Virtual pins in quartus. I can assign each output pin to only be a virtual pin and not an actual pin. With this setup I can have as many output pins as I require and not really connect them to anything.
Quartus Virtual Pins
The design still doesn't scale up to 3000 for some reason, but I have reached out to Intel for that. The original issue of optimizing away the DSP blocks unless they are connected to an output is solved.
The other solution that solved this issue was to chain several of these DSP blocks together. It also doesn't scale, but solves the original question asked here as well.

Bits Not Shifting

I want to be able to create a shift from right to left everytime I press a button, but my simulation says my bits is not shifting.
this is the code I wrote:
module Sipo(KEY0, qIN, qOUT, LEDsipo);
input KEY0;
output reg [5:0] qIN;
output reg [5:0] qOUT;
output [6:0] LEDsipo;
assign LEDsipo[0] = qIN[0];
assign LEDsipo[1] = qIN[1];
assign LEDsipo[2] = qIN[2];
assign LEDsipo[3] = qIN[3];
assign LEDsipo[4] = qIN[4];
assign LEDsipo[5] = qIN[5];
assign LEDsipo[6] = KEY0;
always #(KEY0) begin
if (KEY0 == 1)
qIN = 6'b000000;
qOUT[0] <= KEY0;
qOUT[1] <= qOUT[0];
qOUT[2] <= qOUT[1];
qOUT[3] <= qOUT[2];
qOUT[4] <= qOUT[3];
qOUT[5] <= qOUT[4];
if (qOUT == 7'b111111)
qOUT[0] = 0;
qOUT[1] = 0;
qOUT[2] = 0;
qOUT[3] = 0;
qOUT[4] = 0;
qOUT[5] = 0;
qIN = qOUT;
end
endmodule
The result I got in the simulation is that LEDsipo[0] was responding to KEY0, but the rest of the LEDsipo was not. I don't see why my bits are not shifting.
It is dificult to test your code without a testbench, which you have not provided, but I thik that you rissue is an extra exposure to python.
Verilog does not understand indentation as scope indicators and requires begin/end to indicats scopes. So, my guess is that you have at least several issues:
missing begin/end: if (KEY0 == 1) begin...end
incorrect mix of non-blocing/non-blocking assignments mix
Incorrect coding of your latch
bad use of veriog syntax
so, though it is corret, you can avoid using separate bits:
assign LEDsipo[6:0] = {KEY0, qIN[5:0]};
do not use sensititivity lists in the latch, it will not synthesize correctly in your case. Use always #* instead. Well, and begin/end.
I do not know why you need qIn, but it makes no sense to initialize it to 0 in the first place. Also, it is not a part of the latch and should be moved out of the always block.
always #* begin
if (KEY0 == 1) begin // need begin/end for multiple statements
// qIN <= 6'b000000; -- why do you need it?
qOut[5:0] <= {qOut[4:0], KEY0};
if (qOUT == 7'b111111) // can omit begin/end for a single statement
qOut <= 6'b0;
end
end
assign qIn = qOut;
Since you have not provide any testbench, I did not test the code.

Synthesizable Verilog modular shift register

I'm doing a LOTTT of pipelining with varying width signals and wanted a SYNTHESIZEABLE module wherein i could pass 2 parameters : 1) number of pipes (L) and 2) width of signal (W).
That way i just have to instantiate the module and pass 2 values which is so much simple and robust than typing loads and loads of signal propagation via dummy registers...prone to errors and et all.
I have HALF written the verilog code , kindly request you to correct me if i am wrong.
I AM FACING COMPILE ERROR ... SEE COMMENTS
*****************************************************************
PARTIAL VERILOG CODE FOR SERIAL IN SERIAL OUT SHIFT REGISTER WITH
1) Varying number of shifts / stages : L
2) Varying number of signal / register width : W
*****************************************************************
module SISO (clk, rst, Serial_in, Serial_out); // sIn -> [0|1|2|3|...|L-1] -> sOut
parameter L = 60; // Number of stages
parameter W = 60; // Width of Serial_in / Serial_out
input clk,rst;
input reg Serial_in;
output reg Serial_out;
// reg [L-1:0][W-1:0] R;
reg [L-1:0] R; // Declare a register which is L bit long
always #(posedge clk or posedge rst)
begin
if (rst) // Reset = active high
//**********************
begin
R[0] <= 'b0; // Exceptional case : feeding input to pipe
Serial_out <= 'b0; // Exceptional case : vomiting output from pipe
genvar j;
for(j = 1; j<= L; j=j+1) // Ensuring ALL registers are reset when rst = 1
begin : rst_regs // Block name = reset_the_registers
R[L] <= 'b0; // Verilog automatically assumes destination width # just using 'b0
end
end
else
//**********************
begin
generate
genvar i;
for(i = 1; i< L; i=i+1)
begin : declare_reg
R[0] <= Serial_in; // <---- COMPILE ERROR POINTED HERE
R[L] <= R[L-1];
Serial_out <= R[L-1];
end
endgenerate;
end
//**********************
endmodule
//**********************
Why so complicated? The following code would be much simpler and easier to understand:
module SISO #(
parameter L = 60, // Number of stages (1 = this is a simple FF)
parameter W = 60 // Width of Serial_in / Serial_out
) (
input clk, rst,
input [W-1:0] Serial_in,
output [W-1:0] Serial_out
);
reg [L*W-1:0] shreg;
always #(posedge clk) begin
if (rst)
shreg <= 0;
else
shreg <= {shreg, Serial_in};
end
assign Serial_out = shreg[L*W-1:(L-1)*W];
endmodule
However, looking at your code there are the following problems:
You declare Serial_in as input reg. This is not possible, an input cannot be a reg.
You are using generate..endgenerate within an always block. A generate block is a module item and cannot be used in an always block. Simply remove the generate and endgenerate statements and declare i as integer.
Obviously Serial_in and Serial_out must be declared as vectors of size [W-1:0].
You are using R as a memory. Declare it as such: reg [W-1:0] R [0:L-1].
You are not using i in you for loop. Obviously you meant to chain all the elements of R together, but you are just accessing the 0th, (L-1)th and Lth element. (Obviously the Lth element is nonexisting, this array would be going from 0 to L-1.
I'm now stopping writing this list because, I'm sorry, I think there really is not much to gain by improving the code you have posted..

Can't identify unsafe latch behaviour or completeness of case statement in Verilog code

Hey I'm trying to create a small module that reads which button is pressed on a DE2 4x4 matrix board and then display which column and which row is being pressed on the LED's but I'm having a few problems.
Right now the Columns work but not the rows. I think it has something to do with the fact that the LEDS I use to display the row status have "unsafe latch behaviour" but I'm not too sure.
I have also noticed that for my case statement only ever resolves to the default statement and I don't know why and it says it can't check for completeness.
Would anybody be able to help me? If so thank you very much.
module MatrixInput(MInput, MOutput, LEDR);
input [16:10] MInput; //cols
output reg [24:18] MOutput; //rows
output reg [7:0] LEDR;
reg [31:0] counter; //just setting to max size for now
reg [31:0] i;
reg LEDFlag;
initial begin
counter = 0;
i = 7;
LEDFlag = 0;
end
always#(*) begin
case(counter)
0: MOutput = 7'b0x1x1x1;
1: MOutput = 7'b1x0x1x1;
2: MOutput = 7'b1x1x0x1;
3: MOutput = 7'b1x1x1x0;
default: MOutput = 7'b1x0x0x0;
endcase
LEDR[7] = MInput[10];
LEDR[6] = MInput[12];
LEDR[5] = MInput[14];
LEDR[4] = MInput[16];
repeat(4) begin //step through each col
if (LEDR[i] == 1) //set the LED flag on if any of the col LEDS on
LEDFlag = 1;
if (i != 3) //count down from 7 to 3
i = i - 1;
else
i = 7;
end
LEDR[counter] = LEDFlag;
LEDFlag = 0;
if (counter != 4)
counter = counter + 1;
else
counter = 0;
end
endmodule
There are a number of issues here, I'll give you some hints to get started. Number one is you need some kind of clock to make the counter actually count in a way that you can observe. Otherwise it just zips around like an infinite loop in software (actually, the synthesis tool is probably smart enough to see this and not synthesize any logic at all). Second, initial works only in simulation, but it is not a synthesizable construct. When you power up the logic, counter is going to be at some random value which will likely not match any of the 0-3 cases you have defined, which is why it always goes to the default case. You need a reset and to specify a reset value.

How to constrain a counter reg size in verilog for ise synthesis?

I want to declare a counter reg in function of some parameters. I did it in this way :
parameter clk_freq = 95000; // clock frequency in kHz
parameter debounce_per_ms = 20;
localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
reg [$ln(MAX_COUNT)/$ln(2):0] count;
This work well in simulation with icarus but ISE 14.7 don't want to synthesize it. That give this error:
WARNING:HDLCompiler:1499 - "/src/button_deb.v" Line 4: Empty module <button_deb> remains a black box.
If I define the count like this :
reg [22:0] count;
ISE synthesize it well. If someone have a clue ?
This worked for me, although I'd swear I used functions like $log, $log10, $ceil and the like in the past with no problems.
module param_with_log2 (
input wire clk,
output wire d
);
function integer log2;
input integer value;
begin
value = value-1;
for (log2=0; value>0; log2=log2+1)
value = value>>1;
end
endfunction
parameter clk_freq = 95000; // clock frequency in kHz
parameter debounce_per_ms = 20;
localparam MAX_COUNT = ((debounce_per_ms * clk_freq)) + 1;
localparam integer UPPER = log2(MAX_COUNT);
reg [UPPER:0] count;
always #(posedge clk)
count <= count + 1;
assign d = count[UPPER];
endmodule
XST seems to have a problem with using constant functions: they only can be at the right side of a parameter declaration expression (as I suggested in my first comment). Credits and more information here:
http://www.beyond-circuits.com/wordpress/2008/11/constant-functions/
Notice too that UPPER is declared as localparam integer so we can use it inside a register definition upper bound expression. Credits go to the owner of this post: http://forums.xilinx.com/t5/Synthesis/XST-and-clog2/m-p/244440/highlight/true#M6609
(the module is just a phony module to have something that I can symthesize without the fear that the synthesizer will wipe all my code. It doesn't perform any kind of debouncing)

Resources