在FPGA中24`d9_999_999啥意思
时间: 2023-11-25 16:04:55 浏览: 78
在FPGA中,`24'd9_999_999`表示一个24位的二进制数,它的值为9999999。在Verilog中,`24'd`表示使用24位二进制数来表示一个十进制数字,数字后面的下划线只是为了方便阅读,不会对数值产生影响。
具体来说,24位二进制数可以表示的最大值是2^24 - 1,即16777215,而9999999小于这个值,因此可以用24位二进制数来表示。在Verilog中,我们可以使用`24'd9999999`或`24'd9_999_999`来表示这个数值,它们是等价的。
在FPGA设计中,我们常常需要使用数字常量来表示各种参数,如计数器的初始值、FIFO的深度等等。使用十进制数字常量虽然方便,但在Verilog中使用二进制数字常量可以更加清晰地表示各种数据位的含义,避免了十进制数字常量在不同上下文中的混淆。
相关问题
基于FPGA的数字时钟系统设计
基于FPGA的数字时钟系统设计可以实现时间显示、准确计时、时间校准、定时闹钟等功能。下面是该系统的总体设计和开发过程:
1. 系统总体设计
该系统的总体设计包括时钟模块、计时模块、显示模块、校准模块和闹钟模块。其中,时钟模块提供时钟信号,计时模块实现时间的计时和设置,显示模块将时间信息显示在数码管上,校准模块用于校准时间,闹钟模块实现定时闹钟功能。
2. 源代码开发过程
(1)时钟模块
时钟模块的主要功能是提供时钟信号。在Verilog语言中,可以使用always块和#延时语句来实现时钟信号的产生。具体代码如下:
```verilog
module clock(
input clk, // 输入时钟信号
output reg clk_out // 输出时钟信号
);
always @(posedge clk) begin
#5 clk_out <= ~clk_out; // 每5个时钟周期翻转一次
end
endmodule
```
(2)计时模块
计时模块的主要功能是实现时间的计时和设置。在Verilog语言中,可以使用计数器来实现时间的计时和设置。具体代码如下:
```verilog
module timer(
input clk, // 输入时钟信号
input reset, // 复位信号
input start, // 开始计时信号
input set, // 设置时间信号
input [3:0] hour_set, // 设置小时数
input [5:0] min_set, // 设置分钟数
input [5:0] sec_set, // 设置秒数
output reg [3:0] hour, // 当前小时数
output reg [5:0] min, // 当前分钟数
output reg [5:0] sec // 当前秒数
);
reg [3:0] hour_reg; // 小时数寄存器
reg [5:0] min_reg; // 分钟数寄存器
reg [5:0] sec_reg; // 秒数寄存器
always @(posedge clk or posedge reset) begin
if (reset) begin
hour_reg <= 4'd0;
min_reg <= 6'd0;
sec_reg <= 6'd0;
end else if (start) begin
if (sec_reg == 6'd59) begin
sec_reg <= 6'd0;
if (min_reg == 6'd59) begin
min_reg <= 6'd0;
if (hour_reg == 4'd23) begin
hour_reg <= 4'd0;
end else begin
hour_reg <= hour_reg + 1;
end
end else begin
min_reg <= min_reg + 1;
end
end else begin
sec_reg <= sec_reg + 1;
end
end else if (set) begin
hour_reg <= hour_set;
min_reg <= min_set;
sec_reg <= sec_set;
end
end
assign hour = hour_reg;
assign min = min_reg;
assign sec = sec_reg;
endmodule
```
(3)显示模块
显示模块的主要功能是将时间信息显示在数码管上。在Verilog语言中,可以使用数码管驱动芯片来实现数码管的显示。具体代码如下:
```verilog
module display(
input clk, // 输入时钟信号
input reset, // 复位信号
input [3:0] hour, // 当前小时数
input [5:0] min, // 当前分钟数
input [5:0] sec, // 当前秒数
output reg [6:0] seg, // 数码管段选信号
output reg [3:0] dig // 数码管位选信号
);
reg [26:0] count; // 计数器
always @(posedge clk or posedge reset) begin
if (reset) begin
count <= 27'd0;
end else begin
count <= count + 1;
end
end
always @(count) begin
case(count[3:0])
4'd0: begin
seg <= 7'b0111111; // 数码管显示“0”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd1: begin
seg <= 7'b0000110; // 数码管显示“1”
dig <= 4'b1101; // 第二个数码管位选信号为“1101”
end
4'd2: begin
seg <= 7'b1011011; // 数码管显示“2”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd3: begin
seg <= 7'b1001111; // 数码管显示“3”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd4: begin
seg <= 7'b1100110; // 数码管显示“4”
dig <= 4'b1101; // 第二个数码管位选信号为“1101”
end
4'd5: begin
seg <= 7'b1101101; // 数码管显示“5”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd6: begin
seg <= 7'b1111101; // 数码管显示“6”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd7: begin
seg <= 7'b0000111; // 数码管显示“7”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd8: begin
seg <= 7'b1111111; // 数码管显示“8”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd9: begin
seg <= 7'b1101111; // 数码管显示“9”
dig <= 4'b1110; // 第一个数码管位选信号为“1110”
end
4'd10: begin
seg <= 7'b0000001; // 数码管显示“.”
dig <= 4'b1011; // 第三个数码管位选信号为“1011”
end
4'd11: begin
seg <= 7'b0000001; // 数码管显示“.”
dig <= 4'b0111; // 第四个数码管位选信号为“0111”
end
4'd12: begin
seg <= 7'b0000001; // 数码管显示“.”
dig <= 4'b0011; // 第五个数码管位选信号为“0011”
end
4'd13: begin
seg <= 7'b0000001; // 数码管显示“.”
dig <= 4'b0001; // 第六个数码管位选信号为“0001”
end
4'd14: begin
seg <= 7'b0000001; // 数码管显示“.”
dig <= 4'b0000; // 所有数码管关闭
end
4'd15: begin
seg <= 7'b0000001; // 数码管显示“.”
dig <= 4'b1111; // 所有数码管打开
end
default: begin
seg <= 7'b0000000; // 数码管关闭
dig <= 4'b0000; // 所有数码管关闭
end
endcase
end
endmodule
```
(4)校准模块
校准模块的主要功能是校准时间。在Verilog语言中,可以使用开关和按键来实现时间的校准。具体代码如下:
```verilog
module calibration(
input clk, // 输入时钟信号
input reset, // 复位信号
input [3:0] hour, // 当前小时数
input [5:0] min, // 当前分钟数
input [5:0] sec, // 当前秒数
input set, // 设置时间信号
input [3:0] hour_set, // 设置小时数
input [5:0] min_set, // 设置分钟数
input [5:0] sec_set // 设置秒数
);
reg [1:0] state; // 状态寄存器
always @(posedge clk or posedge reset) begin
if (reset) begin
state <= 2'd0;
end else begin
case(state)
2'd0: begin
if (set) begin
state <= 2'd1;
end
end
2'd1: begin
if (!set) begin
state <= 2'd2;
end
end
2'd2: begin
state <= 2'd0;
end
default: begin
state <= 2'd0;
end
endcase
end
end
assign hour = (state == 2'd1) ? hour_set : hour;
assign min = (state == 2'd1) ? min_set : min;
assign sec = (state == 2'd1) ? sec_set : sec;
endmodule
```
(5)闹钟模块
闹钟模块的主要功能是实现定时闹钟功能。在Verilog语言中,可以使用比较器和触发器来实现定时闹钟功能。具体代码如下:
```verilog
module alarm(
input clk, // 输入时钟信号
input reset, // 复位信号
input [3:0] hour, // 当前小时数
input [5:0] min, // 当前分钟数
input [5:0] sec, // 当前秒数
input [3:0] hour_alarm, // 闹钟小时数
input [5:0] min_alarm, // 闹钟分钟数
output reg alarm_out // 闹钟触发信号
);
always @(hour or min or sec) begin
if ((hour == hour_alarm) && (min == min_alarm) && (sec == 6'd0)) begin
alarm_out <= 1'b1;
end else begin
alarm_out <= 1'b0;
end
end
endmodule
```
以上就是基于FPGA的数字时钟系统设计的开发过程。如果你想深入了解该系统的实现细节,可以参考引用和引用中的详细说明。
基于fpga的oled数字钟代码
以下是基于 FPGA 的 OLED 数字钟的 Verilog 代码示例,其中使用了 PGL50H-6FBG484 开发板和 SSD1306 OLED 驱动芯片。
```verilog
module OLED_Clock (
input clk, // 时钟信号
input rst, // 复位信号
input [3:0] btn, // 按键信号
output reg [7:0] sda, // OLED SDA 数据信号
output reg sclk, // OLED SCK 时钟信号
output reg rs, // OLED RS 控制信号
output reg rst_oled // OLED 复位信号
);
// OLED 驱动芯片的命令定义
localparam CMD_SET_CONTRAST = 0x81;
localparam CMD_DISPLAY_ON = 0xAF;
localparam CMD_DISPLAY_OFF = 0xAE;
localparam CMD_SET_MODE = 0x20;
localparam CMD_SET_PAGE = 0xB0;
localparam CMD_SET_COL_HIGH = 0x10;
localparam CMD_SET_COL_LOW = 0x00;
// OLED 显示屏的参数定义
localparam WIDTH = 128;
localparam HEIGHT = 32;
localparam PAGE_NUM = 4;
localparam COL_NUM = 16;
// 时钟和分钟计数器
reg [5:0] second_cnt = 0;
reg [5:0] minute_cnt = 0;
// 时钟和分钟的数码管显示值
reg [3:0] hour_disp = 0;
reg [3:0] minute_disp = 0;
// OLED 显示屏缓存
reg [7:0] oled_buf [0:HEIGHT*PAGE_NUM-1];
// 计算时钟和分钟的显示值
always @(posedge clk) begin
if (rst) begin
second_cnt <= 0;
minute_cnt <= 0;
end else begin
if (second_cnt == 59) begin
second_cnt <= 0;
if (minute_cnt == 59) begin
minute_cnt <= 0;
end else begin
minute_cnt <= minute_cnt + 1;
end
end else begin
second_cnt <= second_cnt + 1;
end
end
hour_disp <= $unsigned({2'b0, btn[2:1]}) + 1;
minute_disp <= $unsigned({4'b0, btn[3:0]});
end
// 数码管显示模块
module SegDisplay (
input [3:0] value, // 需要显示的数值
output reg [7:0] seg // 数码管段选信号
);
always @(*) begin
case (value)
4'd0: seg = 8'b11000000;
4'd1: seg = 8'b11111001;
4'd2: seg = 8'b10100100;
4'd3: seg = 8'b10110000;
4'd4: seg = 8'b10011001;
4'd5: seg = 8'b10010010;
4'd6: seg = 8'b10000010;
4'd7: seg = 8'b11111000;
4'd8: seg = 8'b10000000;
4'd9: seg = 8'b10010000;
default: seg = 8'b11111111;
endcase
end
endmodule
// 数码管显示模块实例化
SegDisplay hour_disp_i (
.value(hour_disp),
.seg(oled_buf[0][11:4])
);
SegDisplay minute_disp_i (
.value(minute_disp),
.seg(oled_buf[0][3:0])
);
// OLED 显示屏控制模块
always @(posedge clk) begin
if (rst) begin
rs <= 0;
rst_oled <= 1;
sclk <= 0;
sda <= 0;
for (i = 0; i < WIDTH*PAGE_NUM; i = i + 1)
oled_buf[i] <= 0;
end else begin
case (second_cnt)
6'd0: sda <= 8'b00111000; // 初始化 OLED 显示屏
6'd1: begin
rs <= 0;
sclk <= 0;
sda <= CMD_SET_CONTRAST;
end
6'd2: begin
rs <= 1;
sclk <= 0;
sda <= 0x7F; // 设置 OLED 对比度
end
6'd3: begin
rs <= 0;
sclk <= 0;
sda <= CMD_SET_MODE;
end
6'd4: begin
rs <= 0;
sclk <= 0;
sda <= 0x00; // 设置 OLED 显示模式为水平模式
end
6'd5: begin
rs <= 0;
sclk <= 0;
sda <= CMD_SET_PAGE + 0; // 设置 OLED 显示页面
end
6'd6: begin
rs <= 0;
sclk <= 0;
sda <= CMD_SET_COL_HIGH; // 设置 OLED 显示列高位地址
end
6'd7: begin
rs <= 0;
sclk <= 0;
sda <= CMD_SET_COL_LOW; // 设置 OLED 显示列低位地址
end
6'd8: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][7:0]}; // 在 OLED 显示屏上显示数码管
end
6'd9: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][15:8]};
end
6'd10: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][23:16]};
end
6'd11: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][31:24]};
end
6'd12: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][39:32]};
end
6'd13: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][47:40]};
end
6'd14: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][55:48]};
end
6'd15: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][63:56]};
end
6'd16: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][71:64]};
end
6'd17: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][79:72]};
end
6'd18: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][87:80]};
end
6'd19: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][95:88]};
end
6'd20: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][103:96]};
end
6'd21: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][111:104]};
end
6'd22: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][119:112]};
end
6'd23: begin
rs <= 1;
sclk <= 0;
sda <= {8'h00, oled_buf[0][127:120]};
end
6'd24: begin
rs <= 0;
sclk <= 0;
sda <= CMD_DISPLAY_ON; // 打开 OLED 显示屏
end
6'd25: begin
rs <= 1;
sclk <= 0;
sda <= 0x00;
rst_oled <= 0; // 使能 OLED 显示屏复位信号
end
default: begin
rs <= 1;
sclk <= 0;
sda <= 0x00;
end
endcase
// 产生 OLED SCK 时钟信号
if (second_cnt % 2 == 0) begin
sclk <= 1;
end else begin
sclk <= 0;
end
// 处理 OLED 显示屏缓存
for (i = 1; i < PAGE_NUM; i = i + 1) begin
oled_buf[i*HEIGHT+7: i*HEIGHT] <= oled_buf[(i-1)*HEIGHT-1: (i-1)*HEIGHT-8];
end
end
end
endmodule
```
该代码实现了一个简单的 OLED 数字钟,其具体实现方式可能因开发板和 OLED 驱动芯片型号不同而有所不同。根据实际情况,需要修改约束文件和一些硬件参数,以确保代码能够在目标 FPGA 上正确运行。
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![-](https://csdnimg.cn/download_wenku/file_type_lunwen.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)