对于HDLBits Exams/ece241 2013 q4题
标答是从有限状态机入手,分析电路状态的转换以及输出与状态的关系,然后写出驱动方程和状态方程并以此编写描述语言,代码如下:
module top_module (
input clk,
input reset,
input [3:1] s,
output reg fr3,
output reg fr2,
output reg fr1,
output reg dfr
);
// Give state names and assignments. I'm lazy, so I like to use decimal numbers.
// It doesn't really matter what assignment is used, as long as they're unique.
// We have 6 states here.
parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
reg [2:0] state, next; // Make sure these are big enough to hold the state encodings.
// Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.
always @(posedge clk) begin
if (reset) state <= A2;
else state <= next;
end
// Combinational always block for state transition logic. Given the current state and inputs,
// what should be next state be?
// Combinational always block: Use blocking assignments.
always@(*) begin
case (state)
A2: next = s[1] ? B1 : A2;
B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
D1: next = s[3] ? D1 : C2;
default: next = 'x;
endcase
end
// Combinational output logic. In this problem, a procedural block (combinational always block)
// is more convenient. Be careful not to create a latch.
always@(*) begin
case (state)
A2: {fr3, fr2, fr1, dfr} = 4'b1111;
B1: {fr3, fr2, fr1, dfr} = 4'b0110;
B2: {fr3, fr2, fr1, dfr} = 4'b0111;
C1: {fr3, fr2, fr1, dfr} = 4'b0010;
C2: {fr3, fr2, fr1, dfr} = 4'b0011;
D1: {fr3, fr2, fr1, dfr} = 4'b0000;
default: {fr3, fr2, fr1, dfr} = 'x;
endcase
end
endmodule
然而我的描述更趋向于编写顺序执行的程序,注重过程,我认为自己应该学习标答中从电路逻辑入手的方法,区分程序语言和硬件描述语言思路的不同之处
module top_module (
input clk,
input reset,
input [3:1] s,
output fr3,
output fr2,
output fr1,
output dfr
);
reg [3:1]state;
always@(posedge clk)begin
if(reset)begin
state <= 0;
fr3 <= 1;
fr2 <= 1;
fr1 <= 1;
dfr <= 1;
end
else begin
if(s > state)begin
dfr <= 0;
fr1 <= ~(s==3'b111);
fr2 <= (s==3'b001)|(s==3'b000);
fr3 <= (s==3'b000);
end
else if(s == state) begin
dfr <= dfr;
fr1 <= fr1;
fr2 <= fr2;
fr3 <= fr3;
end
else begin
dfr <= 1;
fr1 <= ~(s==3'b111);
fr2 <= (s==3'b001)|(s==3'b000);
fr3 <= (s==3'b000);
end
state <= s;
end
end
endmodule