I'm trying to learn Verilog using Pong P. Chu's book. I have a question about how an always block is evaluated and implemented. A style in the authors code is confusing me.
In this example he codes an FSM with two output registers 'y1' and 'y2'. The part I'm confused about is in the NEXT STATE LOGIC AND OUTPUT LOGIC always block, where after the begin statement and always@*
y1 and y0 are set to 0. I seems that regardless of state, y1 and y0 will toggle to 0 on every clock cycle and signal change. According to state diagram in the book reg y1 should be equal to 1 while in state 0 or 1.
So does y1 toggle to 0 every clock cycle then back to what ever its value at the present state?? I assume that's not the case and that I'm just confused about how the block is evaluated. Can someone explain what that part of the code is doing. I'm lost. Thanks
module fsm_eg_2_seg
(
input wire clk, reset, a, b,
output reg y0, y1
);
//STATE DECLARATION
localparam [1:0] s0 =2'b00,
s1=2'b01,
s2=2'b10;
// SIGNAL DECLARATION
reg [1:0] state_reg, state_next ;
//STATE REGISTER
always @(posedge clk, posedge reset)
if (reset)
state_reg <= s0;
else
state_reg <= state_next;
//NEXT STATE LOGIC AND OUTPUT LOGIC
always @*
begin
state_next = state_reg; // default next state: the same
y1 = 1'b0; // default output: 0
y0 = 1'b0; // default output: 0
case (state_reg)
s0: begin
y1 = 1'b1;
if (a)
if(b)
begin
state_next = s2;
y0 = 1'b1;
end
else
state_next = s1;
end
s1: begin
y1 = 1'b1;
if (a)
state_next = s0;
end
s2: state_next = s0;
default: state_next = s0;
endcase
end
endmodule
The expression
always @* begin : name_of_my_combinational_logic_block
// code
end
describes combinational logic. Typically the clk and rst signals are not read from inside of this type of always block, so they don't appear in the sensitivity list like wisemonkey says. It is best practice to use @* for the sensitivity lists of combinational logic so that you don't forget to include a signal, which would infer some memory and it would no longer be combinational logic.
Inside a combinational logic block, you should use what are called blocking assignments. These look like regular variable assignments in most programming languages and use a single equals. The value that you assign to a variable (a reg) inside of a combinational logic block happens immediately with respect to other statements and expressions in that same combinational logic block, but does not propagate outside of this combinational logic block until you reach the end. The always block must reach the end before any changes are seen outside of the block. Paul S is right that you want to always assign something to your variables whenever the always block is executed, otherwise you will infer memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With