FPGA入门实验
實驗一
用1個撥碼開關控制所有的LED燈亮滅
畫原理圖:
定義管腳:
結果圖:
實驗二
**1、放置2個2-4譯碼器模塊,則總共有2組SW,每組2個,2組LED,每組4個,每組SW分別控制其對應的LED組。
?2、參照代碼,設計一個3-8譯碼器,完成類似的撥碼開關實驗。注意代碼中的信號寬度設定。
?3、自行查閱手冊中的7段譯碼器管腳對應關系,用4個撥碼開關控制一個7段譯碼器的數字,從0-9-A-F,共16個數字和字母**
1
2
參照代碼,設計一個3-8譯碼器,完成類似的撥碼開關實驗。注意代碼中的信號寬度設定。
3
自行查閱手冊中的7段譯碼器管腳對應關系,用4個撥碼開關控制一個7段譯碼器的數字,從0-9-A-F,共16個數字和字母**
實驗三
**1、參照代碼,設計一個0-17的計數器,當計數值為17的時候,OV輸出1,其他輸出0,注意設定合理的信號位寬。
?2、針對以上計數器,修改輸出邏輯,當計數值為0-8時,OV輸出0,9-17時OV輸出1
?用SignalTap驗證
?嘗試并思考,如果時鐘是50MHz,把OV接到一個LED上,能看見什么現象,為什么?**
1
參照代碼,設計一個0-17的計數器,當計數值為17的時候,OV輸出1,其他輸出0,注意設定合理的信號位寬。
2
**針對以上計數器,修改輸出邏輯,當計數值為0-8時,OV輸出0,9-17時OV輸出1
?用SignalTap驗證**
tools->netlist viewers->RTL viewer
tools->signaltap II logic analyzer
?嘗試并思考,如果時鐘是50MHz,把OV接到一個LED上,能看見什么現象,為什么?
實驗四
**1、參照代碼,把后級計數器的計數范圍改為0-15。
.2、把計數器的0-15計數值經過譯碼,在DE0 的 HEX LED上顯示成0-9-A-F的十六 進制數
.3、把計數器的0-15計數值經過譯碼,在DE0 的 HEX LED上顯示成0-9-A-F的十六 進制數
.4、自行設計上面計時器的附加控制功能(清零、暫停)。
17**
1、參照代碼,把后級計數器的計數范圍改為0-15。
2
把計數器的0-15計數值經過譯碼,在DE0 的 HEX LED上顯示成0-9-A-F的十六 進制數
3
把計數器的0-15計數值經過譯碼,在DE0 的 HEX LED上顯示成0-9-A-F的十六 進制數
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 5_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule
module cnt_en_0to99(
CLK , // clock
CNTVAL, // counter value
EN ,
OV ); // overflow
input CLK;
input EN;
output [8-1:0] CNTVAL;
output OV;
reg [8-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 99)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
always @ (CNTVAL) begin
if(CNTVAL == 99)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule // module cnt_en_0to99
module dec4_16(out,in);
output [8-1:0] out;
input [8-1:0] in;
reg [8-1:0] out;
always @(in)
begin
case(in / 10)
4’d0: out=8’b01000000;
4’d1: out=8’b01111001;
4’d2: out=8’b00100100;
4’d3: out=8’b00110000;
4’d4: out=8’b00011001;
4’d5: out=8’b00010010;
4’d6: out=8’b00000010;
4’d7: out=8’b01111000;
4’d8: out=8’b00000000;
4’d9: out=8’b00010000;
endcase
end
endmodule
module dec4_16L(outl,in);
output [8-1:0] outl;
input [8-1:0] in;
reg [8-1:0] outl;
always @(in)
begin
case(in % 10)
4’d0: outl=8’b11000000;
4’d1: outl=8’b11111001;
4’d2: outl=8’b10100100;
4’d3: outl=8’b10110000;
4’d4: outl=8’b10011001;
4’d5: outl=8’b10010010;
4’d6: outl=8’b10000010;
4’d7: outl=8’b11111000;
4’d8: outl=8’b10000000;
4’d9: outl=8’b10010000;
endcase
end
endmodule
4
自行設計上面計時器的附加控制功能(清零、暫停)
//0.1S
module cnt_sync_1(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 5_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule
//1S
module cnt_sync_2(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 50_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule
// module cnt_en_0to9
module cnt_en_0to9(
CLK , // clock
CNTVAL, // counter value
reset, //clear to 0
EN ,
OV ); // overflow
input CLK,reset;
input EN;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(reset)
CNTVAL <= 0;
else begin
if(EN==0) begin // work enable
if(CNTVAL >= 9)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
end
always @ (CNTVAL) begin
if(CNTVAL == 9)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule // module cnt_en_0to9
module bcd7seg (Y,A);
input [3:0] A ;
wire [3:0] A ;
output [6:0] Y ;
wire [6:0] Y ;
assign Y =~Y_r;
reg [6:0] Y_r;
always @(A)begin
Y_r = 7’b1111111;
case (A )
4’b0000: Y_r = 7’b0111111; // 0
4’b0001: Y_r = 7’b0000110; // 1
4’b0010: Y_r = 7’b1011011; // 2
4’b0011: Y_r = 7’b1001111; // 3
4’b0100: Y_r = 7’b1100110; // 4
4’b0101: Y_r = 7’b1101101; // 5
4’b0110: Y_r = 7’b1111101; // 6
4’b0111: Y_r = 7’b0000111; // 7
4’b1000: Y_r = 7’b1111111; // 8
4’b1001: Y_r = 7’b1101111; // 9
4’b1010: Y_r = 7’b1110111; // A
4’b1011: Y_r = 7’b1111100; // b
4’b1100: Y_r = 7’b0111001; // c
4’b1101: Y_r = 7’b1011110; // d
4’b1110: Y_r = 7’b1111001; // E
4’b1111: Y_r = 7’b1110001; // F
default: Y_r = 7’b0000000;
endcase
end
endmodule
// bcd7seg (Y,A)
實驗五
編譯下載電路觀察現象 ? 撥動SW0開關,觀察LED的閃爍變換情況 ? 設計新的功能 – 在原有的電路基礎上,添加方向選擇功能。 – SW0仍然是移位寄存器組的輸入 – 使用SW1開關,控制移位寄存的方向 – 從實驗現象上應當能夠看到,SW1可以控制LED閃爍的移動方向,以及控制SW0值的對LED組的輸入位置(即從LED組的最左邊或是最右邊)
串入并出移位寄存器 /
module shift_reg_SIPO(
RST , // 異步復位, 高有效
CLK , // 時鐘,上升沿有效
EN , // 輸入數據串行移位使能
IN , // 輸入串行數據
OUT ,
CHOSS ); // 并行輸出數據
parameter SHLEN = 6;
input RST, CLK, EN,CHOSS;
input IN;
output[SHLEN-1:0] OUT;
reg [SHLEN-1:0] shift_R;
assign OUT[SHLEN-1:0] = shift_R[SHLEN-1:0];
// 時序邏輯 根據輸入使能進行串行移位
// shift_R 會被編譯為D觸發器
always @ (posedge CLK or posedge RST) begin
if(RST)
shift_R[SHLEN-1:0] <= 0;
else
if(EN&CHOSS) begin // 串行移位的使能有效
shift_R[SHLEN-1:1] <= shift_R[SHLEN-2:0];
shift_R[0] <= IN;
end
end // always
endmodule
時間基準計數器 /
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 25_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule // module cnt_en_0to9
module cnt_en_0to9(
CLK , // clock
CNTVAL, // counter value
EN ,
OV ); // overflow
input CLK;
input EN;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 9)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
always @ (CNTVAL) begin
if(CNTVAL == 9)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule // module cnt_en_0to9
module cnt_0to9(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= 9)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1’b1;
end
always @ (CNTVAL) begin
if(CNTVAL == 9)
OV = 1’b1;
else
OV = 1’b0;
end
endmodule // module cnt_0to9
module dec_2to4(
IN ,
OUT);
input [2-1:0] IN ;
output [4-1:0] OUT ;
reg [4-1:0] OUT ;
always @ (IN) begin
case(IN)
2’b00: OUT = 4’b 0001;
2’b01: OUT = 4’b 0010;
2’b10: OUT = 4’b 0100;
2’b11: OUT = 4’b 1000;
endcase
end
endmodule // module dec_2to4;
**結果是,由于不能拍視頻演示,用文字描述如下
當不撥動sw1時,撥上開關sw0,LED燈從左到右依次亮起,LEDG5->LEDG0
把開關sw0撥下來,燈從左到右依次熄滅。
當把Sw0撥上去時,情況恰好相反。保持Sw0撥上去的狀態,把sw1撥上去,LED燈從右到左依次亮起,把開
關sw1撥下來,LED燈從右到左依次熄滅。**
另附上幾張結果圖**
實驗六
**設計直接數字頻率合成(DDS)
要求:
–用計數器生成地址、讀取ROM數據
–理解二進制補碼和無符號數
–修改計數增量值,觀察波形變化,思考輸出頻率
和計數器增量值的關系。**
根據參考代碼,沒有改動,新建工程等等,這里不再贅述。
計數器模塊內部電路結構:
ROM內部電路結構:
【思考】:如果加法器溢出了,輸出結果會怎樣?
【答】:當相位累加器的溢出時,—個完整的階梯正弦信號就從ROM查詢表的輸出端輸出。因此,相位累加器的溢出率就是正弦波信號的輸出頻率。
不同的計數增量值對應的波形
1 計數增量為1時,正弦波頻率約0.39 MHZ
2 計數增量為2時,正弦波頻率約0.78 MHZ
3 計數增量為8時,正弦波頻率3.125MHZ
(注:計數器的增量由開關決定,共有128種組合)
問題一 撥動開關,觀察不同頻率的正弦波, 電路的工作時鐘是50MHz
(1) 請回答,你能得到的正弦波頻率和計數器增量值的對應關系是什么?
(2)請回答,你能得到的最低頻率的正弦波是多少?設該頻率為f1
(3)請思考,能否有什么方法能夠得到比f1頻率還低的正弦波
【答】:
(1)正弦波頻率和計數器增量值成 線性關系。
(2)正弦波的最低頻率f1約0.39 MHZ。
(3)增加計數器增量或減小計數器數據位寬。
問題二
直接數字頻率合成(DDS)
– 請給出:輸出信號頻率 和 電路工作時鐘頻率,計數器增量值,以及計數器數據位寬
之間的表達式關系。**
學生實驗:*設計直接數字頻率合成(DDS)*
**要求:
–把計數增量輸入信號分配到10個撥碼開關上
–把計數值信號的高7位分配為ROM的地址,低3位懸空不使用。
–編譯、下載電路,撥動撥碼開關,觀察最低頻率有什么變化。**
由于要求是把計數增量輸入信號分配到10個撥碼開關上 ,所以把計數器的輸入端口即開關從7位改成10位即可,其余代碼不變,這里也不再贅述。見下圖。
計數器模塊內部電路結構:
ROM內部電路結構:
最終結果圖:計數增量為03Fh(十六進制)時,即為63時,根據公式,正弦波頻率約3.076MHZ
以上為FPGA的六個基礎實驗,望批評指正。
以上實驗采用的芯片均為Altera公司的Cyclone III 芯片。
2015年6月2日,Altera公司被英特爾以167億美元價格收購。總之,英特爾認為FPGA會無處不在。在網絡世界,FPGA已經在蜂窩基站中亮相,英特爾可能希望借助FPGA在這一領域獲得更多的市場占有率。
總結
- 上一篇: 远古魔力 | 在Windows 10和A
- 下一篇: 睡眠时的局部目标记忆再激活