练习8 利用有限状态机进行时序逻辑设计
源代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 18:29:57 07/29/2019
// Design Name:
// Module Name: seqdet_test
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module seqdet_test(
x,
z,
clk,
rst,
state
);
input x,clk,rst;
output z;
output [2:0]state;
reg [2:0]state;
wire z;
parameter IDLE = 'd0,A = 'd1,B = 'd2,
C = 'd3,D = 'd4,
E = 'd5,F = 'd6,
G = 'd7;
assign z = (state == E && x == 0)?1:0;
//当x序列10010最后一个0刚到时刻,时钟沿立刻将状态变成E,此时z应该变成高
always @(posedge clk)
if(!rst)
begin
state <= IDLE;
end
else
casex(state)
IDLE : if(x == 1)
begin
state <= A; //第一个码位正确,记为A
end
A : if(x == 0)
begin
state <= B; //第二个码位正确,记为B
end
B : if(x == 0)
begin
state <= C; //第三个码位正确,记为C
end
else
begin
state <= F; //前功尽弃,101,记为F,有问题,为何不是A
end
C : if(x == 1)
begin
state <= D; //第四个码位正确,记为D
end
else
begin
state <= G;//前功尽弃,1000,记为G
end
D : if(x == 0)
begin
state <= E;//第五个码位正确,记为E
end
else
begin
state <= A;
//第五个码位不对,10011但是刚进入的1位有用,所以回到第一个码位对应位置,即为A状态
end
E : if(x == 0)
begin
state <= C;
//连着前面输入的x序列,考虑10010,又输入了0码位可以认为第三个码位已对,记为状态C
end
else
begin
state <= A;//前功尽弃,只有刚输入的1码位有用,记为A状态
end
F : if(x == 1)
begin
state <= A;
end
else //输入的0码位正确,记为B
begin
state <= B;
end
G : if(x == 1)
begin
state <= F; //书中是F,为何不是A
end
default : state = IDLE; //默认为初始状态
endcase
endmodule
测试代码
`timescale 1ns / 1ns
// Company:
// Engineer:
//
// Create Date: 19:39:38 07/29/2019
// Design Name: seqdet_test
// Module Name: D:/FPGA/project/seqdet_test/testbench/vtf_seqdet_test.v
// Project Name: seqdet_test
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: seqdet_test
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module vtf_seqdet_test;
// Inputs
// reg x;
reg clk;
reg rst;
reg [23:0]data;
// Outputs
wire x,z;
wire [2:0] state;
assign x = data[23];
always #10 clk = ~clk;
always @(posedge clk)
data = {data[22:0],data[23]}; //数据向左移动
// Instantiate the Unit Under Test (UUT)
seqdet_test uut (
.x(x),
.z(z),
.clk(clk),
.rst(rst),
.state(state)
);
initial begin
// Initialize Inputs
clk = 0;
rst = 1;
#2 rst = 0;
#30 rst = 1;
data = 'b1100_1001_0000_0100;
#500 $stop;
end
endmodule
仿真波形
信心最重要