当前位置: 首页 > news >正文

FPGA控制RGB灯WS2812B

文章目录

  • FPGA控制RGB灯WS2812B
    • 1、简介
      • 1.1水一水
      • 1.2程序完成目标
      • 1.3项目工程结构
    • 2、代码
    • 3、仿真代码
    • 4、结果展示

FPGA控制RGB灯WS2812B

1、简介

1.1水一水

最近在学习WS2812B手册,是一个简单的协议编写,做的时间也算是比较久,相对做出了一个较为完善的结果,在此作为分享

想查看协议的可以去到下列链接:

主要特点 (semiee.com)

1.2程序完成目标

1、有多种模式,按下按键key[0],切换模式

2、实现灯闪烁的速度核亮度的控制

3、实现动态显示FPGA四个字符

1.3项目工程结构

image-20230814184957589

2、代码

顶层模块:

module top(input wire clk,input wire rst_n,input wire[2:0] key,output wire din
);
wire ready_r;
wire enbale;
wire[2:0] key_r;
wire[23:0] data;led_ws_control inst_led_ws_control (.clk      (clk),.rst_n    (rst_n),.ready    (ready_r),.key      (key_r),.enable   (enable),.data_out (data));led_ws inst_led_ws (.clk         (clk),.rst_n       (rst_n),.data_enable (enable),.data        (data),.ready       (ready_r),.din         (din));key_debounce #(.N(3)) inst_key_debounce (.clk     (clk),.rst_n   (rst_n),.key_in  (key),.key_out (key_r));endmodule

按键消抖模块:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : 辣子鸡味的橘子,331197689@qq.com
// File   : key_debounce.v
// Create : 
// Revise : 
// Editor : sublime text4, tab size (4)
// Description:按键消抖模块
// -----------------------------------------------------------------------------
module key_debounce #(parameter N = 4,parameter TIME_20MS = 1000_000)(input wire clk,input wire rst_n,input wire[N-1:0] key_in,//四个按键信号输入output reg[N-1:0] key_out//四个按键信号消抖输出
);reg[19:0] cnt;//20ms计数器
wire add_cnt;//计数开始
wire ent_cnt;//计数终止
wire nedge;//下降沿检测reg[N-1:0] key_in_r0;//同步key_in输入信号
reg[N-1:0] key_in_r1;//延迟一个周期
reg[N-1:0] key_in_r2;//延迟两个周期reg flag;//消抖开始标志信号//计数器模块,当addent满足时开始计数,检测到下降沿重新计数,end_ent满足时停止计数,消抖完成
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt<=20'd0;endelse if(add_cnt)beginif(ent_cnt)begincnt<=20'd0;endelse if(nedge)begincnt<=20'd0;endelse begincnt<=cnt+1;endendelse begincnt<=cnt;end
endassign add_cnt = flag;//计数开始条件
assign end_cnt = (cnt == TIME_20MS - 1)&&add_cnt;//终止结束条件,当满足计时到20ms,且满足计时条件时成立//信号延时模块
always @(posedge clk or negedge rst_n) beginif(~rst_n) beginkey_in_r0<={N{1'b1}};key_in_r1<={N{1'b1}};key_in_r2<={N{1'b1}};endelse beginkey_in_r0<=key_in;key_in_r1<=key_in_r0;key_in_r2<=key_in_r1;end
end//检测下降沿,当任意一个按键出现下降沿都会被检测到
assign nedge = |(~key_in_r1&key_in_r2);
assign podge = |(key_in_r1&~key_in_r2);
//消抖开始模块
always @(posedge clk or negedge rst_n) beginif(~rst_n) beginflag<=1'b0;endelse if(nedge|podge)begin//当出现下降沿开始消抖flag<=1'b1;endelse if(end_cnt)begin//当end_cnt满足时停止消抖flag<=1'b0;endelse beginflag<=flag;end
end//输出信号赋值模块,当消抖完毕标志按键按下,出现一个脉冲信号表示按键按下
always @(posedge clk or negedge rst_n) beginif(~rst_n) beginkey_out<=4'b0000;endelse if(end_cnt)beginkey_out<=~key_in_r0;endelse beginkey_out<=4'b0000;end
endendmodule

数据转化模块:

//==================================================================================================
//  Filename      : led_ws.v
//  Created On    : 2023-08-11 16:04:12
//  Last Modified : 2023-08-14 15:45:43
//  Revision      : 
//  Author        : 辣子鸡味的橘子
//  Email         : 331197689@qq.com
//
//  Description   : 这是led_ws模块,主要的作用是将传进来的数据用fifo进行存储,
//                  将fifo中存储的数据,转换为器件的码型输出
//
//==================================================================================================module led_ws(input wire clk,input wire rst_n,input wire data_enable,input wire[23:0] data,//输入的RGB数据output wire ready,//一帧输出输出标志output reg din//转换过后的码
);
//定义变量参数
parameter MAX_RST = 'd20000;
parameter MAX_BIT = 'd23;
parameter MAX_NUM = 'd63;
parameter MAX_T = 'd60;
//目前的数字
wire[4:0] num;wire din_t0;//0码
wire din_t1;//1码reg[7:0] cnt_cyc;
wire add_cnt_cyc;
wire end_cnt_cyc;reg[4:0] cnt_bit;
wire add_cnt_bit;
wire end_cnt_bit;reg[7:0] cnt_num;
wire add_cnt_num;
wire end_cnt_num;reg[15:0] cnt_rst;
wire add_cnt_rst;
wire end_cnt_rst;
//****************************************************************
//--两段式状态机
//****************************************************************
//---------<状态定义及状态转移条件>-----------------------------------parameter   IDLE    =   3'b001,RESET   =   3'b010,DATA    =   3'b100;reg     [2:0]   state   ;wire   idle2reset;wire   reset2data;wire   data2idle;
//---------<状态转移>-----------------------------------always@(posedge clk or negedge rst_n)if(!rst_n)state <= IDLE;else case(state)IDLE    :  if(idle2reset)beginstate<=RESET;endRESET    :   if(reset2data)beginstate<=DATA;endDATA     :    if(data2idle)beginstate<=IDLE;enddefault:state<=state;endcase
//---------<状态转移条件赋值>-----------------------------------assign idle2reset = state == IDLE&&data_enable;assign reset2data = state == RESET&&end_cnt_rst;assign data2idle = state == DATA&&end_cnt_num;
//****************************************************************
//--fifoip核
//****************************************************************
wire fifo_wr;
wire fifo_rd;
wire fifo_empty;
wire fifo_full;
wire[5:0] fifo_usdw;
wire[23:0] fifo_q;
wire[23:0] fifo_data;
assign fifo_data = {data[15:8],data[23:16],data[7:0]};
assign fifo_wr = data_enable;//换成持续信号
assign fifo_rd = end_cnt_bit;fifo	fifo_inst (.aclr ( ~rst_n ),.clock ( clk ),.data ( fifo_data ),.rdreq ( fifo_rd ),.wrreq ( fifo_wr ),.empty ( fifo_empty ),.full ( fifo_full ),.q ( fifo_q ),.usedw ( fifo_usdw ));//---------<周期计数1200ns>-----------------------------------always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_cyc<='d0;endelse if(add_cnt_cyc)beginif(end_cnt_cyc)begincnt_cyc <='d0;endelse begincnt_cyc <= cnt_cyc + 1'b1;endendelse begincnt_cyc<=cnt_cyc;end
end
assign add_cnt_cyc = state == DATA;
assign end_cnt_cyc = add_cnt_cyc && cnt_cyc == MAX_T;//---------<24bit计数>-----------------------------------always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_bit<='d0;endelse if(add_cnt_bit)beginif(end_cnt_bit)begincnt_bit <='d0;endelse begincnt_bit <= cnt_bit + 1'b1;endendelse begincnt_bit<=cnt_bit;end
end
assign add_cnt_bit = end_cnt_cyc;
assign end_cnt_bit = add_cnt_bit && cnt_bit == MAX_BIT;
//---------<64个像素计数>-----------------------------------always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_num<='d0;endelse if(add_cnt_num)beginif(end_cnt_num)begincnt_num <='d0;endelse begincnt_num <= cnt_num + 1'b1;endendelse begincnt_num<=cnt_num;end
end
assign add_cnt_num = end_cnt_bit;
assign end_cnt_num = add_cnt_num && cnt_num == MAX_NUM;
//---------<复位时间计数>-----------------------------------always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_rst<='d0;endelse if(add_cnt_rst)beginif(end_cnt_rst)begincnt_rst <='d0;endelse begincnt_rst <= cnt_rst + 1'b1;endendelse begincnt_rst<=cnt_rst;end
end
assign add_cnt_rst = state == RESET;
assign end_cnt_rst = add_cnt_rst && cnt_rst == MAX_RST;
//目前计数的数字
assign num = 23 - cnt_bit;
// assign din_t0 = cnt_cyc<2?1'b1:1'b0;
// assign din_t1 = cnt_cyc<3?1'b1:1'b0;
assign din_t0 = cnt_cyc<15?1'b1:1'b0;
assign din_t1 = cnt_cyc<30?1'b1:1'b0;
//---------<单项码赋值>-----------------------------------
always @(*) begincase(state)IDLE: din = 1'b0;RESET:din = 1'b0;DATA:beginif(fifo_q[num] == 1'b1)begindin = din_t1;endelse begindin = din_t0;endenddefault:din = 1'b1;endcase
end//准备条件
assign ready = state == IDLE;
endmodule

注意:其中设计到fifo的配置,下列我简单截取一下fifo中的配置

image-20230814183516700

image-20230814183529286

image-20230814183537567

数据控制模块:

//==================================================================================================
//  Filename      : led_ws_control.v
//  Created On    : 2023-08-11 16:08:30
//  Last Modified : 2023-08-14 17:22:26
//  Revision      : 
//  Author        : 辣子鸡味的橘子
//  Email         : 331197689@qq.com
//
//  Description   :这是控制模块,通过按键按下
//  1、按下key[0],显示三种状态,流水灯、彩虹灯、字体动态显示
//  2、按下key[1],控制亮度,按下亮度是减小,注意有限制
//  3、按下key[2],控制变换速度,三档2s、1s、0.5s
//==================================================================================================
module led_ws_control(input wire clk,input wire rst_n,input wire ready,//准备信号,由led_ws发出,当fifo值为空时发出,告诉控制端准备发送数据input wire[2:0] key,output wire enable,//使能信号,64个周期,写入63个数,给fifo进行寄存output wire[23:0] data_out//输出值
);
parameter TIME_2S = 'd99_999_999;
parameter TIME_1S = 'd49_999_999;
parameter TIME_500MS = 'd24_999_999;
wire[5:0] color_num;
wire[4:0] offect_num;
reg[2:0] flag_color;//控制彩灯闪烁
//亮度信号
reg[23:0] data_out_r1;
wire[23:0] data_out_r2;reg[27:0] cnt_max;//灯光时间值
reg[2:0] flag_time;//灯光时间控制状态
//---------<状态定义及状态转移条件>-----------------------------------parameter   IDLE    =  3'b001 ,DATA    =   3'b010,DELAY    = 3'b100;reg     [2:0]   state   ;wire    idle2data;wire    data2delay;wire    delay2idle;
//****************************************************************
//--两段式状态机
//****************************************************************
reg[7:0] cnt;
wire add_cnt;
wire end_cnt;
//ram rom读写使能信号
wire ram_rd;
wire rom_rd;
//打拍延时信号
reg enable1;
reg enbale2;
reg[2:0] flag;//控制信号
reg[23:0] model1;//模式一
reg[23:0] model2;//模式二
wire[23:0] q_out;//ram的输出
wire[23:0] q_out1;//rom的输出//---------<灯光亮度调节>-----------------------------------
//每次按下减小1/2,超过会复位
reg[3:0] cnt_light;
wire add_cnt_light;
wire end_cnt_light;
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_light<='d0;endelse if(add_cnt_light)beginif(end_cnt_light)begincnt_light <='d0;endelse begincnt_light <= cnt_light + 1;endendelse begincnt_light<=cnt_light;end
end
assign add_cnt_light = key[1];
assign end_cnt_light = add_cnt_light && cnt_light == 'd5;
//---------<灯光速度控制>-----------------------------------
always @(posedge clk or negedge rst_n) beginif(~rst_n)beginflag_time<=3'b100;endelse if(key[2])beginflag_time<={flag_time[0],flag_time[2:1]};endelse beginflag_time<=flag_time;end
end
//---------<灯光时间数据寄存>-----------------------------------
always @(*) begincase(flag_time)3'b001:cnt_max = TIME_500MS;3'b010:cnt_max = TIME_1S;3'b100:cnt_max = TIME_2S;default:cnt_max = TIME_2S;endcase
end
//灯光时间time计数器
reg[27:0] cnt_time;
wire add_cnt_time;
wire end_cnt_time;
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_time<='d0;endelse if(add_cnt_time)beginif(end_cnt_time)begincnt_time <='d0;endelse begincnt_time <= cnt_time + 1'b1;endendelse begincnt_time<=cnt_time;end
end
assign add_cnt_time = state == DELAY;
assign end_cnt_time = add_cnt_time && cnt_time == cnt_max;//****************************************************************
//--x坐标计数器
//****************************************************************
reg[2:0] cnt_x;
wire add_cnt_x;
wire end_cnt_x;
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_x<='d0;endelse if(add_cnt_x)beginif(end_cnt_x)begincnt_x <='d0;endelse begincnt_x <= cnt_x + 1'b1;endendelse begincnt_x<=cnt_x;end
end
assign add_cnt_x = rom_rd;
assign end_cnt_x = add_cnt_x && cnt_x == 'd7;
//****************************************************************
//--y坐标计数器
//****************************************************************
reg[2:0] cnt_y;
wire add_cnt_y;
wire end_cnt_y;
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_y<='d0;endelse if(add_cnt_y)beginif(end_cnt_y)begincnt_y <='d0;endelse begincnt_y <= cnt_y + 1'b1;endendelse begincnt_y<=cnt_y;end
end
assign add_cnt_y = end_cnt_x;
assign end_cnt_y = add_cnt_y && cnt_y == 'd7;
//****************************************************************
//--偏移量计数器
//****************************************************************
reg[5:0] cnt_offect;
wire add_cnt_offect;
wire end_cnt_offect;
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_offect<='d0;endelse if(add_cnt_offect)beginif(end_cnt_offect)begincnt_offect <='d0;endelse begincnt_offect <= cnt_offect + 1'b1;endendelse begincnt_offect<=cnt_offect;end
end
assign add_cnt_offect = end_cnt_time;
assign end_cnt_offect = add_cnt_offect && cnt_offect == 'd31;//更换灯光状态
//****************************************************************
//--闪烁灯效果
//****************************************************************
reg[2:0] cnt_state1;
wire add_cnt_state1;
wire end_cnt_state1;
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt_state1<='d0;endelse if(add_cnt_state1)beginif(end_cnt_state1)begincnt_state1 <='d0;endelse begincnt_state1 <= cnt_state1 + 1'b1;endendelse begincnt_state1<=cnt_state1;end
end
assign add_cnt_state1 = end_cnt_time;
assign end_cnt_state1 = add_cnt_state1 && cnt_state1 == 'd8;always @(*) begincase(cnt_state1)'d0:model1 <= 24'b00000000_11111110_00000000; // 红'd1:model1 <= 24'b11001101_11111110_00000000; // 橙'd2:model1 <= 24'b11111110_11111110_00000000; // 黄'd3:model1 <= 24'b11111110_00000000_00000000; // 绿'd4:model1 <= 24'b11111110_00000000_11111110; // 青'd5:model1 <= 24'b00000000_00000000_11111110; // 蓝'd6:model1 <= 24'b00000000_11001100_11001100; // 紫'd7:model1 <= 24'b11111110_11111110_11111110; // 白'd8:model1 <= 24'b11111111_11111111_11111111;   default:model1 = 24'hffffff;endcase
end//更换灯光状态
//****************************************************************
//--流水灯效果
//****************************************************************
assign color_num = (cnt_y+cnt_offect)%8;
always @(*) begincase(color_num)'d7:model2 = 24'b00000000_11111110_00000000; // 红'd6:model2 = 24'b11001101_11111110_00000000; // 橙'd5:model2 = 24'b11111110_11111110_00000000; // 黄'd4:model2 = 24'b11111110_00000000_00000000; // 绿'd3:model2 = 24'b11111110_00000000_11111110; // 青'd2:model2 = 24'b00000000_00000000_11111110; // 蓝'd1:model2 = 24'b00000000_11001100_11001100; // 紫'd0:model2 = 24'b11111110_11111110_11111110; //白default:model2 = 24'hffffff;endcase
end//---------<灯光控制信号>-----------------------------------
always @(posedge clk or negedge rst_n) beginif(~rst_n)beginflag<=3'b001;endelse if(key[0])beginflag<={flag[1:0],flag[2]};endelse beginflag<=flag;end
end
//计数器,用于计算发送数据的个数
always @(posedge clk or negedge rst_n) beginif(~rst_n) begincnt<='d0;endelse if(add_cnt)beginif(end_cnt)begincnt <= 'd0;endelse begincnt <= cnt + 1'b1;endendelse begincnt<=cnt;end
end
assign add_cnt = state == DATA;
assign end_cnt = add_cnt && cnt == 'd63;//****************************************************************
//--延时打拍使能信号,因为ram读取的信号有两拍的延时
//****************************************************************
always @(posedge clk or negedge rst_n) beginif(~rst_n)beginenable1<=1'b0;enbale2<=1'b0;endelse beginenable1<=ram_rd;enbale2<=enable1;end
end//---------<状态转移>-----------------------------------always@(posedge clk or negedge rst_n)if(!rst_n)state <= IDLE;else case(state)IDLE    :  if(idle2data)state<=DATA;DATA    :  if(data2delay)state<=DELAY;DELAY    :  if(delay2idle)state<=IDLE;default :   state <= IDLE;endcase
//---------<状态转移条件赋值>-----------------------------------assign  idle2data = ready&&state==IDLE;assign 	data2delay = end_cnt&&state==DATA;assign  delay2idle = end_cnt_time&&state==DELAY;
//****************************************************************
//--灯光状态3
//****************************************************************
assign offect_num = cnt_offect+cnt_x;
rom rom_inst (.aclr ( ~rst_n ),.address ( cnt_y*32+offect_num ),.clock ( clk ),.rden ( rom_rd ),.q ( q_out1 ));//读写使能定义条件
assign ram_rd = state == DATA;
assign rom_rd = state == DATA;
assign enable = (flag == 3'b100)?enbale2:rom_rd;
//data_out_r1输出值定义
always @(*) begincase(flag)3'b001:data_out_r1 = model1;3'b010:data_out_r1 = model2;3'b100:beginif(enbale2)begin//data_out_r1 = q_out;//RAM显示data_out_r1 = q_out1;//ROM显示endelse begindata_out_r1 = 24'h000000;endenddefault:data_out_r1 = 24'h000000;endcase
end//---------<亮度值控制>-----------------------------------
assign data_out_r2[7:0] = cnt_light == 0?data_out_r1[7:0]:(data_out_r1[7:0]>>cnt_light);
assign data_out_r2[15:8] = cnt_light == 0?data_out_r1[15:8]:(data_out_r1[15:8]>>cnt_light);
assign data_out_r2[23:16] = cnt_light == 0?data_out_r1[23:16]:(data_out_r1[23:16]>>cnt_light);assign data_out = data_out_r2;
endmodule

这里涉及到了rom的配置,我这里简单演示

image-20230814184456505

image-20230814184504786

image-20230814184518894

mif文件内容:

-- Copyright (C) 2015-Endless, CrazyBird Corporation
-- Thank you for use CrazyBird's design toolsDEPTH = 256;
WIDTH = 24;
ADDRESS_RADIX = UNS;
DATA_RADIX = HEX;CONTENT BEGIN0 : ed1c24;
1 : ed1c24;
2 : ed1c24;
3 : ed1c24;
4 : ed1c24;
5 : 000000;
6 : 000000;
7 : 000000;
8 : ed1c24;
9 : ed1c24;
10 : ed1c24;
11 : ed1c24;
12 : ed1c24;
13 : 000000;
14 : 000000;
15 : 000000;
16 : ed1c24;
17 : ed1c24;
18 : ed1c24;
19 : ed1c24;
20 : 000000;
21 : 000000;
22 : 000000;
23 : 000000;
24 : 000000;
25 : 000000;
26 : ed1c24;
27 : ed1c24;
28 : ed1c24;
29 : 000000;
30 : 000000;
31 : 000000;
32 : ed1c24;
33 : 000000;
34 : 000000;
35 : 000000;
36 : 000000;
37 : 000000;
38 : 000000;
39 : 000000;
40 : ed1c24;
41 : 000000;
42 : 000000;
43 : 000000;
44 : ed1c24;
45 : 000000;
46 : 000000;
47 : 000000;
48 : ed1c24;
49 : 000000;
50 : 000000;
51 : 000000;
52 : 000000;
53 : 000000;
54 : 000000;
55 : 000000;
56 : 000000;
57 : 000000;
58 : ed1c24;
59 : 000000;
60 : ed1c24;
61 : ed1c24;
62 : 000000;
63 : 000000;
64 : ed1c24;
65 : 000000;
66 : 000000;
67 : 000000;
68 : 000000;
69 : 000000;
70 : 000000;
71 : 000000;
72 : ed1c24;
73 : 000000;
74 : 000000;
75 : 000000;
76 : ed1c24;
77 : 000000;
78 : 000000;
79 : 000000;
80 : ed1c24;
81 : 000000;
82 : 000000;
83 : 000000;
84 : 000000;
85 : 000000;
86 : 000000;
87 : 000000;
88 : 000000;
89 : 000000;
90 : ed1c24;
91 : 000000;
92 : 000000;
93 : ed1c24;
94 : 000000;
95 : 000000;
96 : ed1c24;
97 : ed1c24;
98 : ed1c24;
99 : ed1c24;
100 : ed1c24;
101 : 000000;
102 : 000000;
103 : 000000;
104 : ed1c24;
105 : ed1c24;
106 : ed1c24;
107 : ed1c24;
108 : ed1c24;
109 : 000000;
110 : 000000;
111 : 000000;
112 : ed1c24;
113 : 000000;
114 : 000000;
115 : ed1c24;
116 : ed1c24;
117 : ed1c24;
118 : ed1c24;
119 : 000000;
120 : 000000;
121 : ed1c24;
122 : ed1c24;
123 : 000000;
124 : 000000;
125 : ed1c24;
126 : ed1c24;
127 : 000000;
128 : ed1c24;
129 : 000000;
130 : 000000;
131 : 000000;
132 : 000000;
133 : 000000;
134 : 000000;
135 : 000000;
136 : ed1c24;
137 : 000000;
138 : 000000;
139 : 000000;
140 : 000000;
141 : 000000;
142 : 000000;
143 : 000000;
144 : ed1c24;
145 : 000000;
146 : 000000;
147 : ed1c24;
148 : 000000;
149 : 000000;
150 : ed1c24;
151 : 000000;
152 : 000000;
153 : ed1c24;
154 : ed1c24;
155 : ed1c24;
156 : ed1c24;
157 : ed1c24;
158 : ed1c24;
159 : 000000;
160 : ed1c24;
161 : 000000;
162 : 000000;
163 : 000000;
164 : 000000;
165 : 000000;
166 : 000000;
167 : 000000;
168 : ed1c24;
169 : 000000;
170 : 000000;
171 : 000000;
172 : 000000;
173 : 000000;
174 : 000000;
175 : 000000;
176 : ed1c24;
177 : 000000;
178 : 000000;
179 : ed1c24;
180 : 000000;
181 : 000000;
182 : ed1c24;
183 : 000000;
184 : 000000;
185 : ed1c24;
186 : 000000;
187 : 000000;
188 : 000000;
189 : 000000;
190 : ed1c24;
191 : ed1c24;
192 : ed1c24;
193 : 000000;
194 : 000000;
195 : 000000;
196 : 000000;
197 : 000000;
198 : 000000;
199 : 000000;
200 : ed1c24;
201 : 000000;
202 : 000000;
203 : 000000;
204 : 000000;
205 : 000000;
206 : 000000;
207 : 000000;
208 : ed1c24;
209 : 000000;
210 : 000000;
211 : 000000;
212 : 000000;
213 : ed1c24;
214 : ed1c24;
215 : 000000;
216 : ed1c24;
217 : ed1c24;
218 : 000000;
219 : 000000;
220 : 000000;
221 : 000000;
222 : 000000;
223 : ed1c24;
224 : ed1c24;
225 : 000000;
226 : 000000;
227 : 000000;
228 : 000000;
229 : 000000;
230 : 000000;
231 : 000000;
232 : ed1c24;
233 : 000000;
234 : 000000;
235 : 000000;
236 : 000000;
237 : 000000;
238 : 000000;
239 : 000000;
240 : ed1c24;
241 : ed1c24;
242 : ed1c24;
243 : ed1c24;
244 : ed1c24;
245 : ed1c24;
246 : 000000;
247 : 000000;
248 : ed1c24;
249 : 000000;
250 : 000000;
251 : 000000;
252 : 000000;
253 : 000000;
254 : 000000;
255 : ed1c24;END;

**注意:**mif文件要放在工程目录下,不然读取不到数据

3、仿真代码

这个仿真代码很简单,注意各个模块中的参数值就行

`timescale 1ns/1ns
module top_tb();reg clk;
reg rst_n;
reg[2:0] key;
wire din;
parameter SYS_CLK = 20;
always #(SYS_CLK/2) clk = ~clk;initial beginclk=1'b0;rst_n=1'b0;#(2*SYS_CLK);rst_n=1'b1;end
defparam inst_top.inst_led_ws_control.TIME_500MS = 1000;
defparam inst_top.inst_led_ws_control.TIME_1S = 2000;
defparam inst_top.inst_led_ws_control.TIME_2S = 4000;
initial begin//彩虹灯模式key = 3'b111;#(SYS_CLK*50);key = 3'b110;#(SYS_CLK*50);key = 3'b111;#(50*SYS_CLK);//字体动态显示模式//  key = 3'b111;// #(SYS_CLK*50);// key = 3'b110;// #(SYS_CLK*50);// key = 3'b111;// #(50*SYS_CLK);//流水灯模式//  key = 3'b111;// #(SYS_CLK*50);// key = 3'b110;// #(SYS_CLK*50);// key = 3'b111;// #(50*SYS_CLK);#2000000;$stop;
end
top inst_top (.clk(clk), .rst_n(rst_n), .key(key), .din(din));endmodule

4、结果展示

1、闪烁灯:

QQ视频20230814185745_-middle-original

2、彩虹灯

QQ视频20230814185741_-middle-original

3、字体动态显示

QQ视频20230814185735_-middle-original

相关文章:

FPGA控制RGB灯WS2812B

文章目录 FPGA控制RGB灯WS2812B1、简介1.1水一水1.2程序完成目标1.3项目工程结构 2、代码3、仿真代码4、结果展示 FPGA控制RGB灯WS2812B 1、简介 1.1水一水 最近在学习WS2812B手册&#xff0c;是一个简单的协议编写&#xff0c;做的时间也算是比较久&#xff0c;相对做出了一…...

【Linux】【驱动】应用层和驱动层传输数据

【Linux】【驱动】应用层和驱动层传输数据 绪论1.如果我在应用层使用系统0 对设备节点进行打开&#xff0c;关闭&#xff0c;读写等操作会发生什么呢? 2 我们的应用层和内核层是不能直接进行数据传输的3 驱动部分的代码4 应用代码5 编译以及运行代码 绪论 Linux一切皆文件! 文…...

【第二阶段】kotlin函数引用

针对上篇传入函数参数我们也可以重新定义一个函数&#xff0c;然后在main中调用时传入函数对象 lambda属于函数类型的对象&#xff0c;需要把普通函数变成函数类型的对象&#xff08;函数引用&#xff09;&#xff0c;使用“&#xff1a;&#xff1a;” /*** You can edit, ru…...

sip网络号角喇叭 sip音柱 POE供电广播音箱 ip网络防水对讲终端 sip网络功放

SV-7042TP网络号角喇叭 一、描述 SV-7042TP是我司的一款SIP网络号角喇叭&#xff0c;具有10/100M以太网接口&#xff0c;内置有一个高品质扬声器&#xff0c;将网络音源通过自带的功放和喇叭输出播放&#xff0c;可达到功率30W。SV-7042TP作为SIP系统的播放终端&#xff0c;可…...

【网络】传输层——TCP(滑动窗口流量控制拥塞控制延迟应答捎带应答)

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 上篇文章对TCP可靠性机制讲解了一部分&#xff0c;这篇文章接着继续讲解。 &#x1f3a8;滑动窗口 在…...

Electron教程_编程入门自学教程_菜鸟教程-免费教程分享

教程简介 Electron是一个是使用JavaScript&#xff0c;HTML和CSS构建跨平台的桌面应用程序框架。 Electron 通过将 Chromium 和 Node.js 合并到同一个运行时环境中&#xff0c;并将其打包为 Mac&#xff0c;Windows 和 Linux 系统下的应用来实现这一目的。 Electron入门教程 …...

LVS负载均衡DR(直接路由)模式

在LVS&#xff08;Linux Virtual Server&#xff09;负载均衡中的DR&#xff08;Direct Routing&#xff09;模式下&#xff0c;数据包的流向如下&#xff1a; 客户端发送请求到负载均衡器&#xff08;LVS&#xff09;的虚拟IP&#xff08;VIP&#xff09;。负载均衡器&#x…...

14 anaconda+pycharm环境管理以及源管理

文章目录 环境管理博主使用的环境环境设置conda常用指令pycharm与环境的连接&#xff08;新2023版本后&#xff09;设置国内镜像&#xff08;源管理&#xff09;常用操作 环境管理 博主使用的环境 Anaconda3-2023.03-Windows-x86_64 pycharm-professional-2023.2 环境设置 …...

【C语言程序设计】C语言基本数据类型与表达式(思考题)

思考题 1、C语言的主要特点有哪些&#xff1f; ①简单紧凑、灵活方便&#xff0c;②是结构化的语言&#xff0c;③运算符丰富&#xff0c;④是一种高效的语言&#xff0c;⑤可直接对硬件进行操作&#xff0c;⑥具有较好的可移植性。 高效性&#xff1a;C语言是一种高级编程语言…...

Linux 网络发包流程

哈喽大家好&#xff0c;我是咸鱼 之前咸鱼在《Linux 网络收包流程》一文中介绍了 Linux 是如何实现网络接收数据包的 简单回顾一下&#xff1a; 数据到达网卡之后&#xff0c;网卡通过 DMA 将数据放到内存分配好的一块 ring buffer 中&#xff0c;然后触发硬中断CPU 收到硬中…...

Python web实战之Django的AJAX支持详解

关键词&#xff1a;Web开发、Django、AJAX、前端交互、动态网页 今天和大家分享Django的AJAX支持。AJAX可实现在网页上动态加载内容、无刷新更新数据的需求。 1. AJAX简介 AJAX&#xff08;Asynchronous JavaScript and XML&#xff09;是一种在网页上实现异步通信的技术。通过…...

spring boot实现实体类参数自定义校验

安装依赖项 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>1、新建实体类 Data public class UserEntity {private String name;private Integer age;…...

网络安全威胁与防御策略

第一章&#xff1a;引言 随着数字化时代的快速发展&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。然而&#xff0c;网络的广泛应用也引发了一系列严峻的网络安全威胁。恶意软件、网络攻击、数据泄露等问题层出不穷&#xff0c;给个人和企业带来了巨大的风险。本文…...

C++:哈希表——模拟散列表

模拟散列表 维护一个集合&#xff0c;支持如下几种操作&#xff1a; 1.“I x”&#xff0c;插入一个数x 2.“Q x”&#xff0c;询问数x是否在集合中出现过 现在要进行N次操作&#xff0c;对于每个询问操作输出对应的结果 输入格式 第一行包含整数N&#xff0c;表示操作数量 …...

项目配置中心介绍

目录 什么是配置中心 为什么要有配置中心 配置中心的做法&#xff08;读取和通知&#xff09; 配置中心优点: 常用的配置中心中间件 什么是配置中心 配置中心就是用来管理项目当中所有配置的系统&#xff0c;也是微服务系统当中不可或缺的一部分。项目的配置文件不放到本地…...

14-案例:购物车

综合案例-购物车 需求说明: 1. 渲染功能 v-if/v-else v-for :class 2. 删除功能 点击传参 filter过滤覆盖原数组 3. 修改个数 点击传参 find找对象 4. 全选反选 计算属性computed 完整写法 get/set 5. 统计 选中的 总价 和 数量 计算属性conputed reduce条件求和 6. 持久化到本…...

上海市青少年算法2023年2月月赛(丙组)

上海市青少年算法2023年2月月赛(丙组)T1 格式改写 题目描述 给定一个仅由拉丁字符组成字符序列,需要改写一些字符的大小写,使得序列全部变成大写或全部变成小写,请统计最少修改多少个字符才能完成这项任务。 输入格式 一个字符序列:保证仅由拉丁字符构成 输出格式 单个整…...

jetpack5.0.2 已经安装了 cudnn 和 tensorrt

在平台 jetson Xavier NX 中想使用 cudnn 和 tensorrt。然后自己下载了相应包并解压&#xff0c;拷贝&#xff0c;编译 安装 cudnn 1.下载对应包文件&#xff0c;例如&#xff1a;cudnn-linux-sbsa-8.4.1.50_cuda11.6-archive.tar.xz 2.解压&#xff0c;移动到解压目录&#…...

我的编程语言学习笔记

前言 作为一名编程初学者&#xff0c;我深知学习编程需要不断积累和记录。在这篇博客文章中&#xff0c;我将分享一些我在学习C/C编程语言过程中记录的常用代码、特定函数、复杂概念以及特定功能。希望能与大家一起切磋进步&#xff01; 常用代码&#xff1a; 1. 输入输出操作…...

一个DW的计算

一个DW的计算 1- 题目: 已知一个DW1.1 要求: 从DW中取出指定的位的值1.1.1 分析1.1.2 实现1.1.3 简化实现1.1.4 验证 2- 题目: 已知一个DW2.1 要求: 从DW中的指定的P和S,取出指定的位的值2.1.1 分析2.1.2 实现 1- 题目: 已知一个DW 有图中所示一行信息&#xff0c;表示一个DW(…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...