The module I'm trying to get working takes in a pulse data stream with pulses occurring between 500 and 12500 clk cycles, and it needs to delay the stream by a specified number of clk cycles between 500 and 12500 clk cycles. But without using a 12500 bit shift register.
I wrote some code that works in the behavioral simulation, but doesn't post-synthesis. I know my solution is probably terrible form from a Verilog coders perspective. This is my jumping off point I'm just trying to get something working just using what my brain comes up with. My specific problem I think shows up in the schematic view pretty clearly, before synthesis the schematic looks like this:
Which already doesn't make sense to me cause zooming in on the output s_OUT
, I see this:
Before Synthesis Schematic Zoomed In
The output seems to just be ground connected to a buffer, but in behavioral simulation it works. After synthesis however the schematic gets rid of all the other stuff not connected to the output and just leaves that buffer and output pin and it no longer works in simulation:
I'd like to know if there's a rule I'm breaking in my Verilog code that's causing this or if its something else:
module data_delay_counter(
input clk,
input en,
input [13:0] ShiftNum,
input s_IN,
output reg s_OUT
);
// counting phase
reg [13:0] cyclesToInputPulse = 0; // counted clk cycles before a pulse
// storage phase
reg [4:0] memoryIndxWrite = 0; // index to write pulse information to
reg [13:0] storage [0:24]; // memory for pulse information
// delay phase
reg [13:0] delayCounter = 0; // output delay counter
// output phase
reg [4:0] memoryIndxRead = 0; // index to read out pulse information from
reg [13:0] cyclesToOutputPulse = 0; // counted clk cycles up to number read out from storage
reg [24:0] unusedStorage = 0; // specifies if storage pulse info has been used or not, 1 for unused 0 for used
always @(posedge clk) begin
if (en == 1) begin
// counting phase
if (s_IN != 1)
cyclesToInputPulse = cyclesToInputPulse + 14'd1;
else begin
// storage phase
cyclesToInputPulse = cyclesToInputPulse + 14'd1;
storage[memoryIndxWrite] = cyclesToInputPulse;
unusedStorage[memoryIndxWrite] = 1;
cyclesToInputPulse = 14'd0;
memoryIndxWrite = memoryIndxWrite + 14'd1;
if (memoryIndxWrite == 25)
memoryIndxWrite = 14'd0;
end
// delay phase
if (delayCounter != ShiftNum)
delayCounter = delayCounter + 1;
// output phase
else begin
cyclesToOutputPulse = cyclesToOutputPulse + 14'd1;
if (cyclesToOutputPulse == storage[memoryIndxRead] && unusedStorage[memoryIndxRead] == 1) begin
s_OUT = 1;
unusedStorage[memoryIndxRead] = 0;
cyclesToOutputPulse = 14'd0;
memoryIndxRead = memoryIndxRead + 14'd1;
if (memoryIndxRead == 25)
memoryIndxRead = 0;
end
else begin
s_OUT = 0;
end
end
end
else begin
cyclesToInputPulse = 0;
memoryIndxWrite = 0;
delayCounter = 0;
cyclesToOutputPulse = 0;
memoryIndxRead = 0;
unusedStorage = 0;
s_OUT = 0;
end
end
always @(ShiftNum) begin
cyclesToInputPulse = 0;
memoryIndxWrite = 0;
delayCounter = 0;
cyclesToOutputPulse = 0;
memoryIndxRead = 0;
unusedStorage = 0;
s_OUT = 0;
end
The process I was thinking to use was have 25, 14 bit registers as memory to handle the worst case of a pulse every 500 cycles and max delay of 12500 cycles, count the cycles to each pulse store them in memory, wait for the delay and output the pulses according to what's stored in memory. And I needed to add that unusedStorage parameter in order to ensure it always used each stored memory delay only once.
The first problem I see is that you are making assignments to signals from multiple always
blocks. For example, s_OUT
is assigned in both of your always
blocks. While this is legal for simulations, it is likely causing problems for synthesis.
Another issue with the 2nd block is that the signal in the sensitivity list (ShiftNum
) is not used within the block; typically, all signals in the list would also be "read" (i.e., appear on the RHS of an assignment). This block does not map to a conventional synthesis construct.
I recommend incorporating all the assignments from the 2nd always
block into the 1st somehow.
If you have log files for your synthesis run, take a look in them. I'd be surprised if you didn't get warning messages for any of this.
It is also good practice to use nonblocking assignments (<=
) in clocked always
blocks.