久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3142|回復(fù): 0
收起左側(cè)

FPGA入門學(xué)習(xí)筆記分享

[復(fù)制鏈接]
ID:80221 發(fā)表于 2019-4-9 18:50 | 顯示全部樓層 |閱讀模式
最近開始入門FPGA,斷斷續(xù)續(xù)做了些筆記。

今天裝了lattice開發(fā)環(huán)境,嘗試模仿歷程,把LED_shining 歷程敲一遍,進行編譯。報錯:

提示為23行有語法錯誤,原因是module最后一個參數(shù)不需要逗號

改掉這里再編譯 提示25行錯誤

定位實際是24行語句少寫了分隔符導(dǎo)致,加上之后再編譯就成功了。

管腳分配,結(jié)合硬件手測分配管腳

兩個輸入 clk_in ,rst_n_in

兩個輸出 led1,led2


2019/2/28
  三個開關(guān)控制RGB led實驗。

module LED (sw,led);
input [2:0] sw;//開關(guān)輸入信號,利用了其中3個開關(guān)
output [2:0] led;//輸出信號到RGB LED
assign led = sw;/assign連續(xù)賦值。
endmodule

我想用3個開關(guān)控制兩個RGB led燈:

代碼改為:

module RGB_LED1(sw,led1,led2);

              input  [2:0] sw;

              output [2:0] led1;

              output [2:0] led2;

            

              assign led1 = sw;

              assign led2 = sw;



endmodule

改為非阻塞賦值的方式:

需要注意的有兩點,

1.輸入port只能是wire型不能定義成reg型。

2.非阻塞賦值必須用在always塊中執(zhí)行

3.if 語句或者case 語句 后面只能跟一句賦值語句,若要跟多句,需要用到begin end語句

4.always塊要定義觸發(fā)信號


module RGB_LED(clk,rst,sw,led1,led2);
input clk,rst;
input [2:0] sw;
output led1,led2;
reg [2:0] led1;
reg [2:0] led2;
always@(posedge clk or negedge rst)

              if(!rst)
                            begin
                                          led1<=0;
                                          led2<=0;
                            end
              else
                            begin
                                          led1<=sw;
                                          led2<=sw;
                            end
endmodule


2019/3/1

開關(guān)控制數(shù)碼管顯示0~F;原例程為:

module LED (seg_data_1,seg_data_2,seg_led_1,seg_led_2);
input[3:0] seg_data_1;
input[3:0] seg_data_2;//小腳丫上第二個數(shù)碼管
output[8:0] seg_led_1;//控制一個數(shù)碼管需要9個信號 MSB~LSB=DIG、DP、G、F、E、D、C、B、A
output [8:0] seg_led_2;//在小腳丫上第二個數(shù)碼管的控制信號  MSB~LSB=DIG、DP、G、F、E、D、C、B、A
reg[8:0] seg [9:0];//定義了一個reg型的數(shù)組變量,相當(dāng)于一個10*9的存儲器,存儲器一共有10個數(shù),每個數(shù)有9位寬
initial//在過程塊中只能給reg型變量賦值,Verilog中有兩種過程塊always和initial
//initial和always不同,其中語句只執(zhí)行一次
begin
seg[0]=9'h3f;//對存儲器中第一個數(shù)賦值9'b00_0011_1111,相當(dāng)于共陰極接地,DP點變低不亮,7段顯示數(shù)字  0
seg[1]=9'h06;//7段顯示數(shù)字  1
seg[2]=9'h5b;//7段顯示數(shù)字  2
seg[3]=9'h4f;//7段顯示數(shù)字  3
seg[4]=9'h66;//7段顯示數(shù)字  4
seg[5]=9'h6d;//7段顯示數(shù)字  5
seg[6]=9'h7d;//7段顯示數(shù)字  6
seg[7]=9'h07;//7段顯示數(shù)字  7
seg[8]=9'h7f;//7段顯示數(shù)字  8
seg[9]=9'h6f;//7段顯示數(shù)字  9
end
assign seg_led_1 = seg[seg_data_1];//連續(xù)賦值,這樣輸入不同四位數(shù),就能輸出對于譯碼的9位輸出
assign seg_led_2 = seg[seg_data_2];
endmodule


原例程用的是數(shù)據(jù)流描述方式(assign)實現(xiàn)的,我改為行為描述方式(initial+always)
并從顯示0~9擴展為顯示0~F
注意的是 initial后面是不需要“:”
Initial 和always后都可以用非阻塞賦值,多個要用包含在begin...end 里。
module SHUMAGUAN(sw,key,led1,led2);
              input [3:0] sw;
              input [3:0] key;
              output led1,led2;
              reg [8:0] led1;
              reg [8:0] led2;
              reg [8:0] seg[16:0];
              initial
                            begin
                                          seg[0] <= 9'h0x3F;
                                          seg[1] <= 9'h0x06;
                                          seg[2] <= 9'h0x5B;
                                          seg[3] <= 9'h0x4F;
                                          seg[4] <= 9'h0x66;
                                          seg[5] <= 9'h0x6D;
                                          seg[6] <= 9'h0x7D;
                                          seg[7] <= 9'h0x07;
                                          seg[8] <= 9'h0x7F;
                                          seg[9] <= 9'h0x6F;
                                          seg[10]<= 9'h0x77;
                                          seg[11]<= 9'h0x7C;
                                          seg[12]<= 9'h0x39;
                                          seg[13]<= 9'h0x5E;
                                          seg[14]<= 9'h0x79;
                                          seg[15]<= 9'h0x71;
                            end
              always@(sw or key)
                            begin
                                          case(sw)
                                                                      4'b0000:led1 <= seg[0];
                                                                      4'b0001:led1 <= seg[1];
                                                                      4'b0010:led1 <= seg[2];
                                                                      4'b0011:led1 <= seg[3];
                                                                      4'b0100:led1 <= seg[4];
                                                                      4'b0101:led1 <= seg[5];
                                                                      4'b0110:led1 <= seg[6];
                                                                      4'b0111:led1 <= seg[7];
                                                                      4'b1000:led1 <= seg[8];
                                                                      4'b1001:led1 <= seg[9];
                                                                      4'b1010:led1 <= seg[10];
                                                                      4'b1011:led1 <= seg[11];
                                                                      4'b1100:led1 <= seg[12];
                                                                      4'b1101:led1 <= seg[13];
                                                                      4'b1110:led1 <= seg[14];
                                                                      4'b1111:led1 <= seg[15];
                                                                      default:led1 <= seg[0];                                                                                   
                                          endcase
                                          case(key)
                                                                      4'b0000:led2 <= seg[0];
                                                                      4'b0001:led2 <= seg[1];
                                                                      4'b0010:led2 <= seg[2];
                                                                      4'b0011:led2 <= seg[3];
                                                                      4'b0100:led2 <= seg[4];
                                                                      4'b0101:led2 <= seg[5];
                                                                      4'b0110:led2 <= seg[6];
                                                                      4'b0111:led2 <= seg[7];
                                                                      4'b1000:led2 <= seg[8];
                                                                      4'b1001:led2 <= seg[9];
                                                                      4'b1010:led2 <= seg[10];
                                                                      4'b1011:led2 <= seg[11];
                                                                      4'b1100:led2 <= seg[12];
                                                                      4'b1101:led2 <= seg[13];
                                                                      4'b1110:led2 <= seg[14];
                                                                      4'b1111:led2 <= seg[15];
                                                                      default:led2 <= seg[0];                                                      
                                          endcase
                            end
Endmodule

2019/3/5
按鍵消抖:
需要掌握兩個概念:
脈沖邊沿檢測:用一個頻率更高的時鐘去觸發(fā)待檢測的信號,用兩個寄存器去存儲相鄰兩個時鐘采集的值,然后進行異或運算,如果不為0,則代表了上升沿或者下降沿。
消抖方法,第一次檢測脈沖,delay20ms,再檢測key是否為低,如果為低則正面按鍵按下。否則認為是抖動。

我寫的代碼如下(有問題):
module key(clk,key,rst,led);
              input key,rst,clk;
              output reg led;
              reg [17:0] count;
              wire key_edge,key_pulse;
              reg key_pre,key_now;
              reg key2_pre,key2_now;
              always@(posedge clk or negedge rst)  //檢測第一次脈沖發(fā)生 key_edge
                            begin
                                          if(!rst)
                                                        begin
                                                                      key_now=1'b1;
                                                                      key_pre=1'b1;
                                                        end
                                          else
                                                        begin
                                                                      key_now <= key;
                                                                      key_pre <= key_now;
                                                        end
                            end
                           
              assign key_edge = key_pre&(~key_now); //按鍵按下產(chǎn)生一個周期正脈沖
            
              always@(posedge clk or negedge rst)  //定時器初始化
                            begin
                                          if(!rst)
                                                        count<=18'h0;
                                          else if(key_edge)
                                                        count<=18'h0;
                                          else
                                                        count<=count+1'h1;
                            end
                           
              always@(posedge clk or negedge rst) //如果有按鍵按下,延時21ms 再檢測一次key
                            begin
                                          if(!rst)
                                                        begin
                                                                      key2_now<=1'b1;
                                                        end
                                          else if(count==18'h3ffff)
                                                        begin
                                                                      key2_now<=key;
                    key2_pre<=key2_now;                                          //這里寫錯了                           
                                                        end
                            end
                           
              //always@(posedge clk or negedge rst)
                            //begin
                                          //if(!rst)
                                                        //key2_pre <=1'b1;
                                          //else
                                                        //key2_pre <=key2_now;
                            //end
                                                      
              assign  key_pulse = key2_pre&(~key2_now);            
            
              always@(posedge clk or negedge rst)
                            begin
                                          if(!rst)
                                                        led<=1'b1;
                                          else if(key_pulse)
                                                        led<=~led;
                                          else
                                                        led<=led;
                            end
endmodule

以上代碼運行后并沒有得到我想要的結(jié)果,按鍵按下亮,松掉熄滅。原因是延時結(jié)束后key2_pre 不應(yīng)該在這里賦值。因為下一個時鐘clk進來時count已經(jīng)不等于18‘h3ffff了,則不會進入賦值



需要改為:
              always@(posedge clk or negedge rst) //如果有按鍵按下,延時21ms 再檢測一次key
                            begin
                                          if(!rst)
                                                        begin
                                                                      key2_now<=1'b1;
                                                        end
                                          else if(count==18'h3ffff)
                                                        begin
                                                                      key2_now<=key;
                                                        end
                            end

              always@(posedge clk or negedge rst)
                            begin
                                          if(!rst)
                                                        key2_pre <=1'b1;
                                          else
                                                        key2_pre <=key2_now;
                            end
  這里比較難理解,key2_now 是等待21ms后真正的按鍵狀態(tài),而key2_pre是key2_now前一個周期的狀態(tài),即為高,所以這是如果真正按鍵按下了,會輸出一個周期的高電平脈沖。如果檢測到這個脈沖,則認為按鍵是真的按下了。

2019/4/9
通過移位寄存器 練習(xí)編寫測試文件,并對仿真結(jié)果進行分析:
移位寄存器源碼:clk 來一次,高位向低位移位,rst 時賦初值
module SHIFT(clk,rst,datain,dataout);
              input clk,rst;
              input [6:0] datain;
              output dataout;
              wire dataout;
              reg [6:0] data;
              always@(posedge clk)
                            if(!rst)
                                          data <= datain;
                            else
                                          begin
                                                        data[6] <= 1'b0;
                                                        data[5] <= data[6];
                                                        data[4] <= data[5];
                                                        data[3] <= data[4];
                                                        data[2] <= data[3];
                                                        data[1] <= data[2];
                                                        data[0] <= data[1];
                                          end
              assign dataout = data[0];
endmodule
測試用例:
測試需要給條件為 clk 翻轉(zhuǎn)周期,rst 持續(xù)時間,以及rst 時給datain 賦的初值

`timescale 1ns/100ps    //
module SHIFT_TEST;
reg clk,rst;
reg [6:0] datain;
wire dataout;
              initial
                            begin
                                          clk = 0;
                                          rst = 1;
                                          datain = 7'b1110101;
                                          #50
                                          rst = 0;
                                          #100
                                          rst = 1;
                            end
always #10 clk = ~clk;
SHIFT u1(
                                                        .clk(clk),
                                                        .rst(rst),
                                                        .datain(datain),
                                                        .dataout(dataout)
         );
Endmodule

仿真結(jié)果如下:

把clk 周期改為20ns 看起來兩個圖有差別,實際上是一樣的,rst 變高后 clk第一個上一個升沿為移出的數(shù)據(jù),從clk上升沿往前看一個周期,其實都是1,移出的數(shù)據(jù)為1010111,

實現(xiàn)了移位的功能。RST 為高的時候數(shù)據(jù)才是有效的,有意思的是在rst為低時,輸出是保持賦值的最低位不變的。

比如改賦值為1110100,clk 周期為20ns 波形如下:


完整的Word格式文檔51黑下載地址:

小腳丫FPGA學(xué)習(xí)筆記.docx (572.01 KB, 下載次數(shù): 22)


評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 男女网站在线观看 | 波多野结衣一区二区三区在线观看 | 色偷偷噜噜噜亚洲男人 | av在线一区二区三区 | 久久综合久久久 | 国产精品久久久久一区二区三区 | 国偷自产av一区二区三区 | 亚洲在线 | www.日韩av.com| 日韩二| www.亚洲免费 | av中文字幕在线 | 91久久精品国产免费一区 | 久久久久综合 | 免费人成在线观看网站 | 色秀网站| 国产午夜精品一区二区三区四区 | 激情三区| 在线欧美| 古装人性做爰av网站 | 好好的日在线视频 | 一区二区久久电影 | av一区在线 | 精品欧美一区二区在线观看 | 亚洲欧洲一区 | 欧美精品在线免费 | 日本久久视频 | 午夜精品久久久久久久久久久久 | 久国产视频 | 国产精品69毛片高清亚洲 | 亚洲乱码国产乱码精品精98午夜 | 超碰在线人人 | a级毛片国产 | 国产精品免费一区二区三区 | 一区二区三区精品在线 | 精品国产精品国产偷麻豆 | 日韩视频专区 | 日韩毛片免费看 | 国产成人精品一区二区三区网站观看 | 国产精品日产欧美久久久久 | 日本三级精品 |