Continue to Site

# How do I interpret that Always_comb is inside of always_ff ?

Status
Not open for further replies.

#### Xenon02

##### Full Member level 2
Hello !

I've got another question about always_ff and always_comb.

Here always_comb is separated and always_ff is also separated.
And this is a loop ? That always_ff provides new input ? and then always_comb is again calculated ?
This is my teacher code but I don't get it why s_x = o_y and in always_ff it is o_y <= s_x.
And o_y isn't defined at the beggining which is wierd.

But here :

Does it change alot if always_comb is inside of always_ff ?

Second question.

How can always_comb be inside of always_ff ? It's like inside of a flipflop there is whole calculations which is wierd. I can't imagine it how it works. Because I only imagine always_ff as D-flipflop and something like o_y <= i_x means the same as i_x input of D flipflop and o_y output Q of D flipflop. So that always_comb is inside of D flipflop looks wierd for me.

The language doesn't allow nested always blocks (and they make no sense at all). At least one line has been apparently deleted in the posted code.
Should be
Code:
14       else
15         s_states <= s_states_next;

The language doesn't allow nested always blocks (and they make no sense at all). At least one line has been apparently deleted in the posted code.
Should be
Code:
14       else
15         s_states <= s_states_next;
So this is incorrect to use always comb inside of always_ff ?
I thought that I can because our teacher used it.
--- Updated ---

module moore_automata (i_clk, i_bit, i_rsn, o_match);

input logic i_clk, i_rsn, i_bit;
output logic o_match;

logic [1:0] s_states, s_states_next;

localparam [1:0]
S0 = 0, S1 = 1, S2 = 2, S3 = 3;

always_ff @(posedge i_clk, negedge i_rsn)
if (i_rsn == 1'b0)
s_states <= S0;
else
s_states <= s_states_next;

always_comb
begin
s_states_next = s_states;
o_match = '0;
case (s_states)
S0: if (i_bit == 1'b1)
s_states_next = S1;

S1: if (i_bit == 1'b1)
s_states_next = S2;
else
s_states_next = S0;

S2: if (i_bit == 1'b0)
s_states_next = S3;
else
s_states_next = S0;

S3: begin
o_match = '1;
if (i_bit == 1'b1)
s_states_next = S1;
else
s_states_next = S0;
end

default:
s_states_next = S0;
endcase
end
endmodule

Here is the code, you were right about deleted part.
But still there is no begin and end for the always_ff so I thought that always_comb is inside of always_ff.

I do have one more question about it.

There shouldn't be o_y = '0; ?
When always_ff gives o_y <= s_x then it comes back to always_comb and there it is s_x = o_y but they were already the same in o_y <= s_x it is repeated. And at the beggining o_y doesn't have value so s_x is undefined.

Last edited:

Procedural blocks can be placed on the module level, not inside other procedural blocks.

Procedural blocks can be placed on the module level, not inside other procedural blocks.
Okey so I understand it that always_comb cannot be inside of always_ff ?

I do have one more question about it.
View attachment 180619
There shouldn't be o_y = '0; ?
When always_ff gives o_y <= s_x then it comes back to always_comb and there it is s_x = o_y but they were already the same in o_y <= s_x it is repeated. And at the beggining o_y doesn't have value so s_x is undefined.

And at the beggining o_y doesn't have value so s_x is undefined.
Yes.
There shouldn't be o_y = '0; ?
o_y can have any value. There are three operation modes of the loadable shift register.
1. i_e = 0: Keep previous o_y value
2. i_e= 1, i_w = 0: Load i_b to o_y
3. i_e= 1, i_w = 1: left shift o_y, shift i_x in to LSB

Line 17 is improper coding style and gives truncation warning. Should be written correctly as
Code:
s_x = {o_y[BITS-2:0], i_x};

You should post code as text instead of screen shots, so people can test and comment it directly.

Last edited:

Line 17 is improper coding style and gives truncation warning. Should be written correctly as
Code:
s_x = {o_y[BITS-2:0], i_x};
I don't get this Line 17, I used it to connect two bits for example
Code:
s_x = {o_z, i_x};
o_z is one bit and i_x is one bit so connecting them I will get 2 bit adress which s_x can take. But here
Code:
s_x = {o_y[BITS-2:0], i_x};
I have 2 bits o_y and 1 bit i_x and connecting them have 3 bits and s_x can have only 2 bits. I don't get it.

I have 2 bits o_y and 1 bit i_x and connecting them have 3 bits and s_x can have only 2 bits. I don't get it.
Yes, with your original code. The compiler is truncating the expression to two bits an gives a warning. My corrected code cuts the leftmost o_y bit, so the concatenation has correct bit width.

Your question suggests that you didn't yet understand code function, forming a serial in - parallel out shift register.

Status
Not open for further replies.