FPGA 學習筆記1
本系列文章用於記錄FPGA學習過程, 類似流水賬,不做總結提煉.
blink LED
設計
模組化設計, 這裡分為 分頻器, led控制器, 復位訊號產生器.
實現
分屏器
module Clk_div
#(
parameter DIV = 5000
)(
input i_clk,
input i_rst,
output o_clk_div
);
parameter DIV_CNT = DIV/2;
reg [15:0] r_cnt = 0;
reg r_clk_div;
assign o_clk_div = r_clk_div;
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
r_cnt <= 0;
else if (r_cnt == DIV_CNT)
r_cnt <= 1;
else
r_cnt <= r_cnt + 1;
end
always @(posedge i_clk or posedge i_rst)
begin
if(i_rst)
r_clk_div <= 0;
else if (r_cnt == DIV_CNT)
r_clk_div <= ~r_clk_div;
else
r_clk_div <= r_clk_div;
end
endmodule
坑: 一開始cnt沒有賦初值, 還懶得寫復位訊號, 就會導致計數器一直不公正,因為沒有處置
led 控制器
module LED_Driver
#(
parameter LED_NUMBER = 1,
parameter LED_ON = 1
)(
input i_ctl,
input i_en,
output [LED_NUMBER-1:0] o_led
);
reg [LED_NUMBER-1:0] r_led;
assign o_led = r_led;
always @ (*) begin
if(i_en) begin
r_led <= i_ctl;
end
else begin
r_led <= ~LED_ON;
end
end
endmodule
坑: 一直都是用的上升沿觸發, 這裡希望的是電平觸發,結果沒注意一直沒訊號
復位訊號生成器
module rst_gen #(
parameter RST_CYCLE = 1
)(
input i_clk,
output o_rst
);
reg r_o_rst = 1;
reg [15:0] r_cnt = 0;
assign o_rst = r_o_rst;
always @(posedge i_clk) begin
if (r_cnt == RST_CYCLE) begin
r_o_rst <= 0;
end
else begin
r_o_rst <= 1;
end
end
always @(posedge i_clk) begin
if (r_cnt == RST_CYCLE) begin
r_cnt <= r_cnt;
end
else begin
r_cnt <= r_cnt + 1;
end
end
endmodule
作用, 每次上電後自動根據時鐘生成一個RST_CYCLE長度的復位訊號.因為只有每次上電的時候初值是0
blink led top
module top(
input i_clk,
output o_led
);
wire rst;
wire clk_8m;
wire clk_locked;
wire clk_1k;
wire led_ctl;
rst_gen rst_gen_inst
(
.i_clk (i_clk),
.o_rst (rst)
);
clk_8m clk_8m_inst
(
.clk_in1 (i_clk),
.clk_out1 (clk_8m),
.locked (clk_locked)
);
Clk_div #(
.DIV (8000)
) clk_div_inst0 (
.i_clk (clk_8m),
.i_rst (rst),
.o_clk_div (clk_1k)
);
Clk_div #(
.DIV (2000)
) clk_div_inst1 (
.i_clk (clk_1k),
.i_rst (rst),
.o_clk_div (led_ctl)
);
LED_Driver
#(
.LED_NUMBER (1),
.LED_ON (1)
) led_inst
(
.i_ctl (led_ctl),
.i_en (clk_locked),
.o_led (o_led)
);
用到一個IP clk, PLL, 作用是可以產生時鐘? 但是卻需要輸入時鐘, 更多的需要去了解PLL.
用到兩個自己的分頻器,因為好像一個不夠, 不知道如果分頻器的引數設定過大超出了16位暫存器的最大值會發生什麼.
電平標準
- TTL: 三極體單端輸出,
- COMS: MOS管單端輸出--功率低,翻轉快,不超過200M,建議小於150M使用
- LVDS: 低壓差分訊號
- LVPECL: 高速差分, 差值更大,抗干擾更強, 速度更快
- TMDS: 差分, 針對HDMI
- SSHT,HSTL:專用DDR儲存器的單端輸出
差分訊號定義
使用原語, vivado 搜 OBUFDS. o-out, buf, DS-差分.
原語: 是fpga內部你硬核,使用電路實現的.