Electronics > FPGA
Verilog blocking statements in always block (SOLVED)
knight:
I need to perform an addition inside an always block (with clock) but one of the operands depends on the previous value, hence I cannot use non-blocking statements as all variables/registers/wires will have same values.
The expression is basically of the form: a = a[i-1] + constant;
So, I code it like this and it works fine.
--- Code: ---always @(posedge clk or negedge rst)
begin
if (~rst)
// initialize all to 0
else
for (i=1;i<8;i++)
begin
a[i] = a[i-1] + constant; // want non-blocking here
end
temp = a[7] + constant; // want non-blocking here
end
--- End code ---
But it creates a lot of combinational logic as there is one more always block which is performing the similar operation and thus limiting the maximum frequency of operation. Is there any way I can use non-blocking statements.
Actual code:
--- Code: ---integer i;
always @(posedge clk or negedge rst)
begin
if (~rst | (sample_count == SAMPLE_COUNT))
begin
temp <= PHASE_WORD;
for (i = 0; i < 8; i = i + 1)
begin
phase_word[i] <= 0;
end
end
else if (adc_data_in_vld_dly0)
begin
phase_word[0] = temp;
for (i = 1; i < 8; i = i + 1)
begin
phase_word[i] = phase_word[i-1] + PHASE_WORD;
end
temp = phase_word[7] + PHASE_WORD;
end
end
--- End code ---
So basically adding phase word and storing the last value in temp register. For example, if PHASE_WORD is 3 then, in the same clock cycle, phase_word should be [3,6,9,12,15,18,21,24] and next clock cycle it begins with 24+3=27, so 27,30,33......
Now all this works fine using "=" blocking statement at the expense of huge combinational blocks.
I was wondering if this can be done using non-blocking statements as it would greatly enhance frequency of operation. Thanks.
BrianHG:
Here is a hint to 1 possible method.
I cannot offer you any other help.
https://github.com/BrianHGinc/YM2149_PSG_system/blob/9cce2dba1c873c40461d01b75e1cb5be9262e5ed/BHG_audio_filter_mixer.sv#L73-L126
But this method takes multiple clock cycles to give a final result.
During these clock cycles, the inputs must be held until the final result is reached.
KrudyZ:
It seems like you could easily unroll the loop.
The output vector is simply the last word of the previous clock cycle plus 1, 2, 3, 4, etc. times your constant.
If it is truly a constant then the numbers get computed at synthesis time, else you will get a set of multipliers which depending on your FPGA architecture could get expensive.
pbernardi:
So basically adding phase word and storing the last value in temp register. For example, if PHASE_WORD is 3 then, in the same clock cycle, phase_word should be [3,6,9,12,15,18,21,24] and next clock cycle it begins with 24+3=27, so 27,30,33......
something like:
--- Code: ---phase_word[i] <= phase_word[0] + i*PHASE_WORD;
--- End code ---
couldnĀ“t do the job?
knight:
--- Quote from: pbernardi on September 30, 2022, 04:02:56 pm ---So basically adding phase word and storing the last value in temp register. For example, if PHASE_WORD is 3 then, in the same clock cycle, phase_word should be [3,6,9,12,15,18,21,24] and next clock cycle it begins with 24+3=27, so 27,30,33......
something like:
--- Code: ---phase_word[i] <= phase_word[0] + i*PHASE_WORD;
--- End code ---
couldnĀ“t do the job?
--- End quote ---
Yes, and temp <= phase_word[0] + 8*PHASE_WORD also worked but still phase_word[0] = temp needs to be blocking. |O
According to Verilog coding guideline, we should not mix blocking and non-blocking in same always block so I just kept it blocking for now until I find a way to assign phase_word[0].
Navigation
[0] Message Index
[#] Next page
Go to full version