Verilog HDL 實作 74HC595
文章目錄
- Verilog HDL 實作 74HC595
- 一、簡介
- 二、代碼實作
- 1、按鍵消抖子產品
- 2、實作功能的子產品
- 三、效果的示範
我們使用Verilog 語言來實作74HC595這個晶片的功能并且進行展示。
一、簡介
74HC595是一個8位串行輸入、并行輸出的位移緩存器:并行輸出為三态輸出。在SCK 的上升沿,串行資料由SDL輸入到内部的8位位移緩存器,并由Q7’輸出,而并行輸出則是在LCK的上升沿将在8位位移緩存器的資料存入到8位并行輸出緩存器。當串行資料輸入端OE的控制信号為低使能時,并行輸出端的輸出值等于并行輸出緩存器所存儲的值。
74HC595是一個8位串行輸入、并行輸出的位移緩存器:并行輸出為三态輸出。在SCK 的上升沿,串行資料由SDL輸入到内部的8位位移緩存器,并由Q7’輸出,而并行輸出則是在LCK的上升沿将在8位位移緩存器的資料存入到8位并行輸出緩存器。當串行資料輸入端OE的控制信号為低使能時,并行輸出端的輸出值等于并行輸出緩存器所存儲的值。
二、代碼實作
這裡我們使用代碼來實作這個晶片的功能并呈現結果:
1、按鍵消抖子產品
我們知道用按鍵,必消抖。
module debounce (clk,rst,key,key_pulse);
parameter N = 1; //要消除的按鍵的數量
input clk;
input rst;
input [N-1:0] key; //輸入的按鍵
output [N-1:0] key_pulse; //按鍵動作産生的脈沖
reg [N-1:0] key_rst_pre; //定義一個寄存器型變量存儲上一個觸發時的按鍵值
reg [N-1:0] key_rst; //定義一個寄存器變量儲存儲目前時刻觸發的按鍵值
wire [N-1:0] key_edge; //檢測到按鍵由高到低變化是産生一個高脈沖
//利用非阻塞指派特點,将兩個時鐘觸發時按鍵狀态存儲在兩個寄存器變量中
always @(posedge clk or negedge rst)
begin
if (!rst) begin
key_rst <= {N{1'b1}}; //初始化時給key_rst指派全為1,{}中表示N個1
key_rst_pre <= {N{1'b1}};
end
else begin
key_rst <= key; //第一個時鐘上升沿觸發之後key的值賦給key_rst,同時key_rst的值賦給key_rst_pre
key_rst_pre <= key_rst; //非阻塞指派。相當于經過兩個時鐘觸發,key_rst存儲的是目前時刻key的值,key_rst_pre存儲的是前一個時鐘的key的值
end
end
assign key_edge = key_rst_pre & (~key_rst);//脈沖邊沿檢測。當key檢測到下降沿時,key_edge産生一個時鐘周期的高電平
reg [17:0] cnt; //産生延時所用的計數器,系統時鐘12MHz,要延時20ms左右時間,至少需要18位計數器
//産生20ms延時,當檢測到key_edge有效是計數器清零開始計數
always @(posedge clk or negedge rst)
begin
if(!rst)
cnt <= 18'h0;
else if(key_edge)
cnt <= 18'h0;
else
cnt <= cnt + 1'h1;
end
reg [N-1:0] key_sec_pre; //延時後檢測電平寄存器變量
reg [N-1:0] key_sec;
//延時後檢測key,如果按鍵狀态變低産生一個時鐘的高脈沖。如果按鍵狀态是高的話說明按鍵無效
always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec <= {N{1'b1}};
else if (cnt==18'h3ffff)
key_sec <= key;
end
always @(posedge clk or negedge rst)
begin
if (!rst)
key_sec_pre <= {N{1'b1}};
else
key_sec_pre <= key_sec;
end
assign key_pulse = key_sec_pre & (~key_sec);
2、實作功能的子產品
module hc (clk,out,in,key,rst);
input clk,in,rst,key;
output reg [7:0]out;
wire key_pulse;
debounce u1 (
.clk (clk),
.rst (rst),
.key (key),
.key_pulse (key_pulse)
);
always @(posedge clk)
begin
if(!rst)
out<=8'b11111111;
else if(key_pulse)
begin
out[0]<=!in;
out[7:1]<=out[6:0];
之後,我們進行編譯:
(這是編譯成功的畫面。)
然後,我們設定引腳的配置設定:
(也就是設定小腳丫的引腳的配置設定。)
最後還需要進行燒錄也就是上傳:
(這是上傳(燒錄)成功的畫面。)
三、效果的示範
參見下面的視訊,要是喜歡的話可以去點個贊嘛:
https://www.bilibili.com/video/BV1iS4y1R7aJ?spm_id_from=333.999.0.0
Verilog HDL 實作 74HC595