第六章 Verilog HDL 高级程序设计举例【Verilog】
- 前言
- 推荐
- 第六章 Verilog HDL 高级程序设计举例
- 状态机
- 用状态机设计1101序列检测器
- 需要定义几个状态?
- 代码设计——端口信号声明
- 状态寄存器
- 次态生成逻辑设计(C1模块)
- 输出逻辑设计(C2模块)
- 完整代码
- 测试结果
- 用状态机设计1101序列检测器
- 不考虑重复序列的状态转移图???
- 用米里状态机设计1101序列检测器
- 完整代码
- 测试结果
- 交通灯
- 输出
- 交通灯的状态转移图
- 代码设计?
- 程序设计-----输入输出信号声明
- 状态寄存器和状态转移逻辑设计
- 输出逻辑设计
- 完整代码
- 测试结果
- 最后
前言
2022/12/3 14:41
以下内容源自Verilog
仅供学习交流使用
推荐
Verilog
第六章 Verilog HDL 高级程序设计举例
状态机
2段式
3段式
Mealy状态机和Moore状态机
用状态机设计1101序列检测器
需要定义几个状态?
代码设计——端口信号声明
module seadeta_moore (
input wire clk,
input wire clr,
input wire din,
output reg dout
);
reg [2:0] present_state, next_state;
parameter s0=3'b000,s1=3 'b001,s2=3 'b010,s3=3'b011,s4=3'b100;
endmodule
状态寄存器
- 确定初始状态
- 每一个clk的上升沿,修改状态寄存器的值
always @(posedge clk or posedge clr)
begin
if(clr==1) present_state<=s0;
else present_state<=next_state;
end
次态生成逻辑设计(C1模块)
- 根据输入和当前状态,决定转移的下一个状态
always @(*)
begin
case (present_state)
s0: if (din==1)next_state=s1;
else next_state=s0;
s1: if(din==1) next_state=s2;
else next_state=s0;
s2: if (din==0) next_state=s3;
else next_state=s2;
s3: if(din==1) next_state =s4;
else next_state= s0;
s4: if(din==0) next_state = s0;
else next_state= s2;
default next_state= s0;
endcase
end
输出逻辑设计(C2模块)
- 根据当前的状态决定当前的输出
always@(*)
begin
if(present_state==s4) dout=1;
else dout =0;
end
完整代码
//moore型
//考虑重复序列
module seadeta_moore (
input wire clk,
input wire clr,
input wire din,
output reg dout
);
//代码设计--端口信号声明
reg [2:0] present_state, next_state;
parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100;
//状态寄存器
//确定初始状态
//每一个clk的上升沿,修改状态寄存器的值
always @(posedge clk or posedge clr)
begin
if(clr==1) present_state<=s0;
else present_state<=next_state;
end
//次态生成逻辑设计(C1模块)
//根据输入和当前状态,决定转移的下一个状态
always @(*)
begin
case (present_state)
s0: if (din==1)next_state=s1;
else next_state=s0;
s1: if(din==1) next_state=s2;
else next_state=s0;
s2: if (din==0) next_state=s3;
else next_state=s2;
s3: if(din==1) next_state =s4;
else next_state= s0;
s4: if(din==0) next_state = s0;
else next_state= s2;
default next_state= s0;
endcase
end
//输出逻辑设计(C2模块)
//根据当前的状态决定当前的输出
always@(*)
begin
if(present_state==s4) dout=1;
else dout =0;
end
endmodule
测试结果
测试
module seadeta_tb;
reg clk;
reg clr;
reg din;
wire dout;
seadeta_moore m1(clk,clr,din,dout);
always
#5 clk=~clk;
initial
begin
clk=0;
clr=1;
#10 clr=0;din=0;
#10 din=1;
#10 din=1;
#10 din=0;
#10 din=1;
#10 din=1;
#10 din=0;
#10 din=1;
#10 din=0;
#10 din=1;
#10 din=1;
#10 din=0;
#10 din=1;
end
endmodule
结果
用状态机设计1101序列检测器
序列检测器就是将一个指定的序列从数字码流中检测出来。
当输入端出现序列1101时,输出为1,否则输出为0。在此不考虑重复序列,即出现指定序列后就重新开始序列检测,不再考虑以前的数据。
不考虑重复序列的状态转移图???
用米里状态机设计1101序列检测器
- 需要定义4个状态。
- 状态转移图
完整代码
//mealy型
//不考虑重复序列
module seadeta_mealy(
input wire clk,
input wire clr,
input wire din,
output reg dout
);
reg [2:0] present_state, next_state;
parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011;
//时序逻辑
always @(posedge clk or posedge clr)
begin
if(clr==1) present_state<=s0;
else present_state<=next_state;
end
//组合逻辑
always @(*)
begin
case (present_state)
s0: if (din==1)begin next_state=s1; dout=0; end
else begin next_state=s0; dout=0; end
s1: if(din==1) begin next_state=s2; dout=0; end
else begin next_state=s0; dout=0; end
s2: if (din==0) begin next_state=s3; dout=0; end
else begin next_state=s2; dout=0; end
s3: if(din==1) begin next_state =s0; dout=1; end
else begin next_state= s0; dout=0; end
default begin next_state= s0; dout=0; end
endcase
end
endmodule
测试结果
测试
module seadeta_tb;
reg clk;
reg clr;
reg din;
wire dout;
//seadeta_moore m1(clk,clr,din,dout);
seadeta_mealy m2(clk,clr,din,dout);
always
#5 clk=~clk;
initial
begin
clk=0;
clr=1;
#10 clr=0;din=0;
#10 din=1;
#10 din=1;
#10 din=0;
#10 din=1;
#10 din=1;
#10 din=0;
#10 din=1;
#10 din=0;
#10 din=1;
#10 din=1;
#10 din=0;
#10 din=1;
end
endmodule
结果
交通灯
输出
交通灯的状态转移图
代码设计?
- 用6个彩色LED等代表一组交通信号灯,为输出
- 行为描述:根据当前的状态点亮熄灭对应的LED灯,计数结束就状态转移
程序设计-----输入输出信号声明
module traffic(
input wire clk,input wire clr,
output reg [5:0]lights
);
reg [2:0]state;
reg [3:0]count;
parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100,s5=3'b101;
parameter sec5=5,sec1=1;
endmodule
状态寄存器和状态转移逻辑设计
always @(posedge clk or posedge clr)
begin
if(clr==1)
begin
state<=s0;
count<=0;
end
else
case (state)
s0: if(count<sec5)
begin
state<=s0;
count<=count+1;
end
else
begin
state<=s1;
count<=0;
end
s1: if(count<sec1)
begin
state<=s1;
count<=count+1;
end
else
begin
state<=s2;
count<=0;
end
s2: if(count<sec1)
begin
state<=s2;
count<=count+1;
end
else
begin
state<=s3;
count<=0;
end
s3: if(count<sec5)
begin
state<=s3;
count<=count+1;
end
else
begin
state<=s4;
count<=0;
end
s4: if(count<sec1)
begin
state<=s4;
count<=count+1;
end
else
begin
state<=s5;
count<=0;
end
s5: if (count<sec1)
begin
state<=s5;
count<=count+1;
end
else
begin
state<=s0;
count<=0;
end
default state<=s0;
endcase
end
输出逻辑设计
always @(*)
begin
case (state)
s0: lights=6'b100001;
s1: lights=6'b100010;
s2: lights=6'b100100;
s3: lights=6'b001100;
s4: lights=6'b010100;
s5: lights=6'b100100;
default lights=6'b100001;
endcase
end
完整代码
module traffic(
input wire clk,input wire clr,
output reg [5:0]lights
);
//程序设计-----输入输出信号声明
reg [2:0]state;
reg [3:0]count;//此位宽由sec5,sec1决定
parameter s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011,s4=3'b100,s5=3'b101;
parameter sec5=5,sec1=1;//此单位为时钟周期
//状态寄存器和状态转移逻辑设计
always @(posedge clk or posedge clr)
begin
if(clr==1)
begin
state<=s0;
count<=0;
end
else
case(state)
s0: if(count<sec5)
begin
state<=s0;
count<=count+1;
end
else
begin
state<=s1;
count<=0;
end
s1: if(count<sec1)
begin
state<=s1;
count<=count+1;
end
else
begin
state<=s2;
count<=0;
end
s2: if(count<sec1)
begin
state<=s2;
count<=count+1;
end
else
begin
state<=s3;
count<=0;
end
s3: if(count<sec5)
begin
state<=s3;
count<=count+1;
end
else
begin
state<=s4;
count<=0;
end
s4: if(count<sec1)
begin
state<=s4;
count<=count+1;
end
else
begin
state<=s5;
count<=0;
end
s5: if (count<sec1)
begin
state<=s5;
count<=count+1;
end
else
begin
state<=s0;
count<=0;
end
default state<=s0;
endcase
end
//输出逻辑设计
always @(*)
begin
case (state)
s0: lights=6'b100001;
s1: lights=6'b100010;
s2: lights=6'b100100;
s3: lights=6'b001100;
s4: lights=6'b010100;
s5: lights=6'b100100;
default lights=6'b100001;
endcase
end
endmodule
测试结果
测试
module traffic_tb;
reg clk;
reg clr;
wire [5:0]lights;
traffic u1(clk,clr,lights);
always
#5 clk=~clk;
initial
begin
clk=0;
clr=1;
#10
clr=0;
end
endmodule
结果
最后
2022/12/3 16:21
这篇博客能写好的原因是:站在巨人的肩膀上
这篇博客要写好的目的是:做别人的肩膀
开源:为爱发电
学习:为我而行