两种方式实现FPGA流水灯仿真(基于ISE13.4)

1、时钟分频实现12位流水灯

module led(
	input clk,										//输入时钟
	output [11:0] led								//led输出
  );
	reg[11:0] led_state=12'b0000_0000_0001;//led初始状态
	reg[31:0] divclk_cnt=0;						//32为计数器
	reg divclk=0;									//分频时钟
	assign led=led_state;
	
	parameter halfduty_cntvalue=1;//0,1为半个周期计两个数,一个周期计4个数,这是4分频
	always@(posedge clk)
	begin
			if(divclk_cnt == halfduty_cntvalue)//分频计数
			begin
				divclk = ~divclk;
				divclk_cnt=0;
			end
			else
				divclk_cnt = divclk_cnt+1;
	end
	/*每个上升沿反转一次,这是2分频,与上面的4分频只能留一个
	always@(posedge clk)
	begin
		divclk = ~divclk;
	end
	*/
	always@(posedge divclk)
	begin
			if(led_state[11]==1)
				led_state=12'b0000_0000_0001;
			else
				led_state=led_state<<1;
	end
endmodule

testbench 如下:

module led12_fixture;
	// Inputs
	reg clk;

	// Outputs
	wire [11:0] led;

	// Instantiate the Unit Under Test (UUT)
	led uut (
		.clk(clk), 
		.led(led)
	);
	initial begin
		// Initialize Inputs
		clk = 0;

		// Wait 100 ns for global reset to finish
		#10;//这里没有写复位信号,可以自行添加
		// Add stimulus here
	end
   always #10 clk=~clk;  
endmodule

仿真结果如下:
在这里插入图片描述

2、通过计数器累加实现4位流水灯

module jishuqi(
	input clk,
	input rst_n,
	output reg[3:0] led_o
    );
	reg[2:0] cnt;//这里为什么计数这么少呢?因为软件默认仿真时长只有1us,计数值一大就
	//会出现只有第一个状态,并不跳变的情况。这个鬼玩意困扰了我一天,我一直以为是我的程
	//序哪里出错了,后来我才发现是这个仿真时长限制的问题。如果要设置较大的计数值一定要
	//修改仿真时长
always@(posedge clk or negedge rst_n)//计数器计数5个上升沿
	begin
		if(!rst_n)
			cnt<=0;
		else if(cnt==4)
			cnt<=0;
		else
			cnt<=cnt+1;	
	end
	
always@(posedge clk or negedge rst_n)//LED控制逻辑
	begin
		if(!rst_n)
			led_o<=4'b0001;
		else if(led_o==4'b1000 && cnt==4)
			led_o<=4'b0001;	
		else if(cnt==4)
			led_o<=led_o<<1;	
	end
/*这是LED控制逻辑的另一种实现方式
always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
			led_o<=4'b0001;
		else if(cnt==4)
			led_o<={led_o[2:0],led_o[3]};//位拼接实现循环移位	
		else 
			led_o<=led_o;	
	end
*/
endmodule

testbench 如下:

module jishuqi_tb;

	// Inputs
	reg clk;
	reg rst_n;

	// Outputs
	wire [3:0] led_o;

	// Instantiate the Unit Under Test (UUT)
	jishuqi uut (
		.clk(clk), 
		.rst_n(rst_n), 
		.led_o(led_o)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		rst_n = 0;
		// Wait 20 ns for global reset to finish
		#20;
      	rst_n = 1;
		// Add stimulus here
	end
   always #10 clk=~clk;   
endmodule

仿真结果如下:
注意图中红圈处的移位跳变。在这里插入图片描述

你可能感兴趣的:(FPGA)