【自学小梅哥fpga】07 led6道题引出线性序列机

先说自己搞明白了一点点小问题:就是仿真文件中定义clk是和D触发器的工作原理对应的(上升沿触发)。
在这里插入图片描述
1~3题其实没什么难度,题目的意义在于,一段时间能等分成几个单位时间,并能对这些单位时间进行控制。除了5题都是一个led(1bit)。

4题

在这里插入图片描述

定义模块代码

module led4 (
	reset_n,
	ttime,
	ctrl,
	clk,
	led
);
	input reset_n;
	input [31:0] ttime;
	input [7:0] ctrl;
	input clk;
	output reg led;
	
reg [31:0] counter1;
reg [2:0] counter2;  //3位二进制能表示8段。

/*****counter1计数*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) counter1<=0;  //always块中有复位信号,先复位清零。
	else if (counter1==(ttime-1)) counter1<=0; 
	else counter1<=counter1+1'b1;
end

/*****counter2计数*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) counter2<=0;  //always块中有复位信号,先复位清零。
	else if (counter1==(ttime-1)) counter2<=counter2+1'b1; 
end

/*****crtl端口控制单位时间的高低电平*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) led<=0;  //always块中有复位信号,先复位清零。
	else case (counter2) 
		3'd0:led<=ctrl[0];
		3'd1:led<=ctrl[1];
		3'd2:led<=ctrl[2];
		3'd3:led<=ctrl[3];
		3'd4:led<=ctrl[4];
		3'd5:led<=ctrl[5];
		3'd6:led<=ctrl[6];
		3'd7:led<=ctrl[7];
		default led<=led;
	endcase
end
endmodule

在这里插入图片描述

6题

在这里插入图片描述

定义模块代码

module led6 (
	reset_n,
	ttime,
	ctrl,
	clk,
	led
);
	input reset_n;
	input [31:0] ttime;
	input [7:0] ctrl;
	input clk;
	output reg led;
	
reg [31:0] counter1;
reg [2:0] counter2; 
reg [18:0] counter3; //10ms
reg EN;

/*****counter1计数*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) counter1<=0;  //always块中有复位信号,先复位清零。
	else if (EN) begin
	    if(counter1==(ttime-1)) counter1<=0; 
    	else counter1<=counter1+1'b1;
	end
	else counter1=0;	
end

/*****counter2计数*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) counter2<=0;  //always块中有复位信号,先复位清零。
	else if(counter1==(ttime-1))counter2<=counter2+1'b1;
end

/*****counter3计数*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) counter3<=0;  //always块中有复位信号,先复位清零。
	else if (counter3==(500000-1)) counter3<=0; 
	else counter3<=counter3+1'b1;
end

/*****EN控制信号*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) EN<=0;  //always块中有复位信号,先复位清零。
	else if (counter3==0)EN<=1;
	else if ((counter2==7)&&(counter1==(ttime-1))) EN<=0;  //计数i次<=>counter2=i。
end

/*****crtl端口控制单位时间的高低电平*****/
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) led<=0;  //always块中有复位信号,先复位清零。
	else case (counter2) 
		3'd0:led<=ctrl[0];
		3'd1:led<=ctrl[1];
		3'd2:led<=ctrl[2];
		3'd3:led<=ctrl[3];
		3'd4:led<=ctrl[4];
		3'd5:led<=ctrl[5];
		3'd6:led<=ctrl[6];
		3'd7:led<=ctrl[7];
		default led<=led;
	endcase
end
endmodule

在这里插入图片描述

测试代码

`timescale 1ns/1ns
module led6_tb;
    reg clk;
    reg [31:0]ttime;
    reg resetn;
    reg [7:0]ctrl;
    wire led;

    led6  led6tb(
    .clk(clk),
    .ttime(ttime),
    .reset_n(resetn),
    .led(led),
    .ctrl(ctrl)
);
    
    initial clk=1;//和posedge clk是对应的。
    always # 10 clk=!clk;
    
    initial begin 
        resetn = 0; 
        ctrl = 0;
        ttime = 0;//端口清零
        #201;
        
        resetn = 1; 
        ctrl=8'b1000_0110;
        ttime=2500;//试验一个值
        # 200000000;
        $stop;
    end 
endmodule

语法

  1. 复位端口清零。清零后,后面的代码不考虑清零状态,因为清零状态是初始值。
    定义模块:
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) counter <=0;
end
always @ (negedge reset_n or posedge clk) begin
	if (reset_n==0) led <=0;
end

仿真模块:

initial begin
	reset_n=0;   //复位。
	ttime=0;  //输入端口清零。
	ctrl=0;
	#201;  //复位清零设置一小段时间。
end
  1. 用case语法的时候,必须考虑case()括号里面的值穷举完了吗?没有穷举完用default补充。
default: led<=led;
  1. 当有多个仿真文件时,选择目的仿真文件为头文件
    在这里插入图片描述
    设置为头文件之后会变成黑色加粗字体。
    在这里插入图片描述
  2. 调试技巧
    将定义模块中的端口添加到波形图中。
    在这里插入图片描述
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值