赞
踩
在Verilog中实现跑马灯通常涉及到使用一个计数器来控制LED灯的亮灭顺序。
跑马灯是一种常见的电子显示方式,它通过控制多个LED灯的顺序点亮,形成一种动态的视觉效果,看起来就像灯在“跑”一样。
使用dip开关控制跑马灯的速度和方向
module led_horse_run #(
parameter LED_ON = 1'b0, //led active low
parameter CLK_FREQ = 50*1000*1000 //frequency of input clock
)(
input clk,
input rst_n,
input wire [5:0] dip_u6,
output reg [5:0] led
);
//
//Local parameter, same as const in c/c++
//For 50Mhz clock,
//one second count to 50*1000*1000
//one millisecond count to 50*1000
//
localparam ONE_SECOND = CLK_FREQ;
localparam HALF_SECOND = ONE_SECOND / 2;
localparam ONE_MSECOND = ONE_SECOND / 1000;
//-------------------------------------------
//control the running speed and direction
//according to the status of dip keys
wire [1:0] speed = dip_u6[1:0];
wire direct = dip_u6[5];
//First style of assignment for combinational logic, (not for sequential logic)
//Note: left value must be wire type, here 'wire [31:0] count_max;'
wire [31:0] count_max;
assign count_max = (speed == 0) ? ONE_MSECOND * 2000 :
(speed == 1) ? ONE_MSECOND * 1000 :
(speed == 2) ? ONE_MSECOND * 500 : ONE_MSECOND * 200;
/*
//another style of assignment of combinational logic
//Note: left value must be reg type, here 'reg [31:0] count_max;'
reg [31:0] count_max;
always @(*) begin
count_max = (speed == 0) ? ONE_MSECOND * 2000 :
(speed == 1) ? ONE_MSECOND * 1000 :
(speed == 2) ? ONE_MSECOND * 500 : ONE_MSECOND * 200;
end
*/
//---------------------------------------------------------
reg [31:0] count;
wire time_on = (count == count_max-1);
always @(posedge clk) begin
if(~rst_n) count <= 0;
else if(time_on) count <= 0;
else count <= count + 1;
end
wire [5:0] init_led_status = (LED_ON == 1'b1) ? 6'b000001 : 6'b111110;
always @(posedge clk) begin
if(~rst_n) led <= init_led_status;
else if(time_on) begin
if(direct == 1'b1) led <= {led[4:0], led[5]} ; //shift left
else led <= {led[0],led[5:1]} ; //shift right
end
//else led <= led;
end
endmodule
适了解流水灯和跑马灯的区别,适当修改上面的跑马灯代码实现流水灯的效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。