代码规范:Verilog 代码规范_verilog代码编写规范-CSDN博客
开发流程:FPGA基础知识----第二章 FPGA 开发流程_fpga 一个项目的整个流程-CSDN博客
源码下载:https://github.com/Redamancy785/FPGA-Learning-Record.git
零、74HC595芯片驱动
1、74HC595串转并芯片 内部原理图
2、74HC595串转并芯片 时序图
3、使用两片74HC595芯片 实现三根数据线传输十六位数据
4、驱动模块设计输入以及目标输出时序图
module hc595_driver(
clk_i,
reset_n_i,
sel_i,
seg_i,
dio_o,
srclk_o,
rclk_o
);
input clk_i,reset_n_i;
input [7:0] sel_i;
input [7:0] seg_i;
output dio_o,srclk_o,rclk_o;
parameter FREQUENCY = 50_000_000; // Hz
parameter SRCLK_FREQUENCY = 12_500_000; // Hz
parameter SRCLK_TURN_INTERVAL = FREQUENCY/SRCLK_FREQUENCY/2;
reg [31:0] srclk_turn_interval_cnt;
always@(posedge clk_i or negedge reset_n_i)
if(!reset_n_i)
srclk_turn_interval_cnt <= 0;
else if(srclk_turn_interval_cnt == (SRCLK_TURN_INTERVAL - 1))
srclk_turn_interval_cnt <= 0;
else
srclk_turn_interval_cnt <= srclk_turn_interval_cnt + 1;
reg [4:0] srclk_turn_cnt;
always@(posedge clk_i or negedge reset_n_i)
if(!reset_n_i)
srclk_turn_cnt <= 0;
else if(srclk_turn_interval_cnt == (SRCLK_TURN_INTERVAL - 1))
srclk_turn_cnt <= srclk_turn_cnt + 1;
reg dio_o;
reg rclk_o;
always@(posedge clk_i)
if(!reset_n_i)
rclk_o <= 0;
else begin
case(srclk_turn_cnt)
0: begin dio_o <= seg_i[7]; rclk_o <= 1; end
1: rclk_o <= 0;
2: dio_o <= seg_i[6];
4: dio_o <= seg_i[5];
6: dio_o <= seg_i[4];
8: dio_o <= seg_i[3];
10: dio_o <= seg_i[2];
12: dio_o <= seg_i[1];
14: dio_o <= seg_i[0];
16: dio_o <= sel_i[7];
18: dio_o <= sel_i[6];
20: dio_o <= sel_i[5];
22: dio_o <= sel_i[4];
24: dio_o <= sel_i[3];
26: dio_o <= sel_i[2];
28: dio_o <= sel_i[1];
30: dio_o <= sel_i[0];
endcase
end
reg srclk_o;
always@(posedge clk_i)
if(!reset_n_i)
srclk_o <= 0;
else begin
case(srclk_turn_cnt%2)
0: srclk_o <= 0;
1: srclk_o <= 1;
endcase
end
endmodule
一、功能定义
二、设计输入
module digital_tube_hc595(
clk_i,
reset_n_i,
switch_i,
dio_o,
srclk_o,
rclk_o
);
input clk_i,reset_n_i;
input [1:0] switch_i;
output dio_o,srclk_o,rclk_o;
reg [31:0] disp_data_i;
wire [7:0] u_sel_o;
wire [7:0] u_seg_o ;
digital_tube U_digital_tube_0(
.clk_i(clk_i),
.reset_n_i(reset_n_i),
.disp_data_i(disp_data_i),
.sel_o(u_sel_o),
.seg_o(u_seg_o)
);
hc595_driver U_hc595_driver_0(
.clk_i(clk_i),
.reset_n_i(reset_n_i),
.sel_i(u_sel_o),
.seg_i(u_seg_o),
.dio_o(dio_o),
.srclk_o(srclk_o),
.rclk_o(rclk_o)
);
always@(*)
case (switch_i)
0 : disp_data_i = 32'h01234567;
1 : disp_data_i = 32'h89abcdef;
2 : disp_data_i = 32'h08192a3b;
3 : disp_data_i = 32'h4c5d6e7f;
endcase
endmodule
三、功能仿真
`timescale 1ns / 1ps
module digital_tube_hc595_tb();
reg u_clk_i,u_reset_n_i;
reg [1:0] u_switch_i;
wire u_dio_o,u_srclk_o,u_rclk_o;
digital_tube_hc595 U_digital_tube_hc595_0(
.clk_i(u_clk_i),
.reset_n_i(u_reset_n_i),
.switch_i(u_switch_i),
.dio_o(u_dio_o),
.srclk_o(u_srclk_o),
.rclk_o(u_rclk_o)
);
initial u_clk_i = 1;
always #10 u_clk_i = ~u_clk_i;
initial begin
u_reset_n_i = 0;
#201;
u_reset_n_i = 1;
u_switch_i = 0;
#10_000_000;
u_switch_i = 1;
#10_000_000;
u_switch_i = 2;
#10_000_000;
u_switch_i = 3;
#10_000_000;
$stop;
end
endmodule