This question is purely about synthesized verliog, not simulated.
I have read that blocking assignments are executed in order, but also that blocking assignments assign values to the RHS immediately. These two seem to contradict each other.
Eg. take a for loop adder:
reg signed [15:0] signalHist [127:0];
integer i;
reg signed [142:0] sum = 0;
wire triggerSum = 0;
...
always @ (posedge clk) begin
if (triggerSum==1) begin
sum = 0;
for (i=0; i<128; i=i+1) begin
sum = sum + signalHist[i];
end
end
In this example's case, how can the value for sum be assigned to its register immediately? What happens if we are summing 1000 or 100000 int16s?
Or, does the word immediately as I used above just mean "after the required amount of processing time"?
If the number of integers being summed gets to be very large (or more generally, if we have too many blocking statements each which depends on the previous), could it be possible that the synthesized circuit would take more than a clock cycle to evaluate?
EDIT:
Below is a simplified version of the code Im trying to run. Its basically a FIR filter. I stripped out the ADC/DAC interfacing sections so that this code:
- Loads data from INDATA[7:0] every 1000 clock cycles (inDataCounter flips every 500 clock cycles)
- On next clock cycle, shifts the array signalHist[] by 1 and puts the new INDATA into the first index
- On next clock cycle, multiplies signalHist[] .* taps[] (point by point) and saves the result in product[]
- On the next clock cycle, sums all of product[] into sumSum
- On the next clock cycle, sets part of the resulting sumSum to OUTDATA (output pins)
always @ (posedge clk)
begin
//Simulate new data clock, every 1000 cycles
if (inDataCounter < 500) begin
inDataCounter <= inDataCounter+1;
end else if (inDataCounter == 500) begin
inDataCounter <= 0;
inDataClk<= ~inDataClk;
// Filter taps, hard coded for now, update-able here
taps[0] <= 271;
taps[1] <= -961;
taps[2] <= 2574;
...
taps[2047] <= 15;
end
triggerSampleAddLast <= triggerSampleAdd;
if (triggerSampleAddLast != triggerSampleAdd) begin
//shift the time array and add the new element
for (jj=2047; jj>0; jj=jj-1) begin
signalHist[jj] <= signalHist[jj-1];
end
signalHist[0] <= adcSample[17:2];
signalHistTrig <= ~signalHistTrig;
end
signalHistTrigLast <= signalHistTrig;
if (signalHistTrigLast != signalHistTrig) begin
for (kk=0; kk<2048; kk=kk+1) begin
product[kk] <= taps[kk]*signalHist[kk];
end
productTrig <= ~productTrig;
end
productTrigLast <= productTrig;
if (productTrigLast != productTrig) begin
sumSum = 0;
for (ll=0; ll<2048; ll=ll+1) begin //4096 or 256 loops
sumSum = sumSum + product[ll];
end
doneReading = ~doneReading;
end
doneReadingLast <= doneReading;
if (doneReadingLast != doneReading) begin
OUTDATA[15:0] <= sumSum[35:20];//signalHist[0];//sumSum[18:3]; //sumSum[18:3];//adc0_sample[17:2];//;//output dac spi word
end
end
And below, the new data sample coming in
always @ (posedge inDataClk) begin
adcSample <= INDATA;
triggerSampleAdd<=~triggerSampleAdd;
end
This takes 269k logic blocks to complete, 1000+% of my FPGA. Is there any way to reduce the number of logic blocks required, by splitting up into multiple cycles?
Is there a better way to split up things onto multiple cycles?