250 likes | 373 Views
Lab 6: FSM Description. Separate combinational and memory circuits State memory uses FFs Others are combinational circuits. Another approach. Traffic Light Controller. TL. The block diagram. HR HG HY FR FG FY. Comb. circuits. FF’s. Comb. circuits. C. n_state. state. TS. ST.
E N D
Lab 6: FSM Description • Separate combinational and memory circuits • State memory uses FFs • Others are combinational circuits
Traffic Light Controller TL • The block diagram HR HG HY FR FG FY Comb. circuits FF’s Comb. circuits C n_state state TS ST ST_o
State transition diagram TL + C Reset S0: HG S1: HY S2: FG S3: FY S0 TL•C/ST TS/ST TS S1 S3 TS TS/ST TL + C/ST S2 TL • C
Verilog Description module traffic_light(HG, HY, HR, FG, FY, FR,ST_o, tl, ts, clk, reset, c) ; output HG, HY, HR, FG, FY, FR, ST_o; input tl, ts, clk, reset, c ; reg ST_o, ST ; reg[0:1] state, next_state ; parameter EVEN= 0, ODD=1 ; parameter S0= 2'b00, S1=2'b01, S2=2'b10, S3=2'b11; assign HG = (state == S0) ; assign HY = (state == S1) ; assign HR = ((state == S2)||(state == S3)) ; assign FG = (state == S2) ; assign FY = (state == S3) ; assign FR = ((state == S0)||(state == S1)) ;
// flip-flops always@ (posedge clk or posedge reset) if(reset) // an asynchronous reset begin state = S0 ; ST_o = 0 ; end else begin state = next_state ; ST_o = ST ; end
always@ (state or c or tl or ts) case(state) // state transition S0: if(tl & c) begin next_state = S1 ; ST = 1 ; end else begin next_state = S0 ; ST = 0 ; end TL + C Reset S0 TL•C/ST TS/ST TS S1 S3 TS TS/ST TL + C/ST S2 TL • C
S1: if (ts) begin next_state = S2 ; ST = 1 ; end else begin next_state = S1 ; ST = 0 ; end S2: if(tl | !c) begin next_state = S3 ; ST = 1 ; end else begin next_state = S2 ; ST = 0 ; end TL + C Reset S0 TL•C/ST TS/ST TS S1 S3 TS TS/ST TL + C/ST S2 TL • C
S3: if(ts) begin next_state = S0 ; ST = 1 ; end else begin next_state = S3 ; ST = 0 ; end endcase endmodule TL + C Reset S0 TL•C/ST TS/ST TS S1 S3 TS TS/ST TL + C/ST S2 TL • C
Counter Design • ST • when active, clear and enable the counter • TL/TS • terminal count • active to disable the counter • ST options • latched or non-latched output • Counter options • synchronous or asynchronous clear
Timer Design • Timer/counter • clk • ST • TL/TS • TL/TS Sync. Clear Async. Clear
Non-latched Output • Synchronous/asynchronous clear clk state TL C ST S1 S0 S0 S0 Async. Clear (ST to TL) Sync. Clear (ST to TL)
Latched Output • Timing Diagram clk state TL/TS C ST_o S1 S2 S1 S0 S0 Async. Clear (ST to TL) Sync. Clear (ST to TL)
FSM Directive • // synopsys state_vector state parameter [2:0] /* synopsys enum bus_states */ S0 = 3'b000, S1 = 3'b001, S2 = 3'b010, S3 = 3'b011, S4 = 3'b100, S5 = 3'b101; reg [2:0] /* synopsys enum bus_states */ state, next_state;
always @ (posedge CLK) begin if (RESET == 1’b1) begin if (ADDR_A == 2’b00) begin DEC_Q[5:4] <= ADDR_D; DEC_Q[3:2] <= 2’b01; DEC_Q[1:0] <= 2’b00; if (ADDR_B == 2’b01) begin DEC_Q[3:2] <= ADDR_A + 1’b1; DEC_Q[1:0] <= ADDR_B + 1’b1; if (ADDR_C == 2’b10) An Inefficient Use of Nested If
begin DEC_Q[5:4] <= ADDR_D + 1’b1; if (ADDR_D == 2’b11) DEC_Q[5:4] <= 2’b00; end else DEC_Q[5:4] <= ADDR_D; end end else DEC_Q[5:4] <= ADDR_D; DEC_Q[3:2] <= ADDR_A; DEC_Q[1:0] <= ADDR_B + 1’b1; end else DEC_Q <= 6’b000000; end
Nested If = priority-encoded logic complex nested if => inefficient
always @ (posedge CLK) begin if (RESET == 1’b1) begin casex (ADDR_ALL) 8’b00011011: begin DEC_Q[5:4] <= 2’b00; DEC_Q[3:2] <= ADDR_A + 1; DEC_Q[1:0] <= ADDR_B + 1’b1; end 8’b000110xx: begin DEC_Q[5:4] <= ADDR_D + 1’b1; DEC_Q[3:2] <= ADDR_A + 1’b1; DEC_Q[1:0] <= ADDR_B + 1’b1; end
8’b0001xxxx: begin DEC_Q[5:4] <= ADDR_D; DEC_Q[3:2] <= ADDR_A + 1’b1; DEC_Q[1:0] <= ADDR_B + 1’b1; end 8’b00xxxxxx: begin DEC_Q[5:4] <= ADDR_D; DEC_Q[3:2] <= 2’b01; DEC_Q[1:0] <= 2’b00; end default: begin DEC_Q[5:4] <= ADDR_D; DEC_Q[3:2] <= ADDR_A; DEC_Q[1:0] <= ADDR_B + 1’b1; end endcase end else DEC_Q <= 6’b000000; end
Case statements creates balanced logic reduces the delay by 3 ns
Case Statement - Avoid Inferred Latch • Use a default assignment or add // synopsys full_case directive Always @ (bcd) begin case (bcd) // synopsys full_case 4’d0: begin out2=0; out1=0; out0=1; end 4’d1: begin out2=0; out1=1; out0=0; end 4’d0: begin out2=1; out1=0; out0=0; end endcase end
Case Statement - Avoid Priority Decoder • To prevent priority decoder inferred, add // synopsys parallel_case directive Always @ (u or v or w or x or y or z) begin case (2’b11) // synopsys parallel_case u: decimal=10’b0000000001; v: decimal=10’b0000000010; w: decimal=10’b0000000100; x: decimal=10’b0000001000; y: decimal=10’b0000010000; z: decimal=10’b0000100000; default: decimal=10’b0000000000; endcase end
Case Statement - Inferred Priority Decoder • A priority decoder may be used (depending on the capability of the synthesis tool) Always @ (u or v or w or x or y or z) begin case (2’b11) u: decimal=10’b0000000001; v: decimal=10’b0000000010; w: decimal=10’b0000000100; x: decimal=10’b0000001000; y: decimal=10’b0000010000; z: decimal=10’b0000100000; default: decimal=10’b0000000000; endcase end
Case Statement - Avoid Priority Decoder • To prevent priority decoder inferred, add // synopsys parallel_case directive Always @ (u or v or w or x or y or z) begin case (2’b11) // synopsys parallel_case u: decimal=10’b0000000001; v: decimal=10’b0000000010; w: decimal=10’b0000000100; x: decimal=10’b0000001000; y: decimal=10’b0000010000; z: decimal=10’b0000100000; default: decimal=10’b0000000000; endcase end