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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3080|回復: 0
打印 上一主題 下一主題
收起左側

FPGA入門學習筆記分享

[復制鏈接]
跳轉到指定樓層
樓主
ID:80221 發表于 2019-4-9 18:50 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
最近開始入門FPGA,斷斷續續做了些筆記。

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

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

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

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

管腳分配,結合硬件手測分配管腳

兩個輸入 clk_in ,rst_n_in

兩個輸出 led1,led2


2019/2/28
  三個開關控制RGB led實驗。

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

我想用3個開關控制兩個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塊中執行

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

4.always塊要定義觸發信號


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

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


原例程用的是數據流描述方式(assign)實現的,我改為行為描述方式(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
按鍵消抖:
需要掌握兩個概念:
脈沖邊沿檢測:用一個頻率更高的時鐘去觸發待檢測的信號,用兩個寄存器去存儲相鄰兩個時鐘采集的值,然后進行異或運算,如果不為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)  //檢測第一次脈沖發生 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); //按鍵按下產生一個周期正脈沖
            
              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

以上代碼運行后并沒有得到我想要的結果,按鍵按下亮,松掉熄滅。原因是延時結束后key2_pre 不應該在這里賦值。因為下一個時鐘clk進來時count已經不等于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后真正的按鍵狀態,而key2_pre是key2_now前一個周期的狀態,即為高,所以這是如果真正按鍵按下了,會輸出一個周期的高電平脈沖。如果檢測到這個脈沖,則認為按鍵是真的按下了。

2019/4/9
通過移位寄存器 練習編寫測試文件,并對仿真結果進行分析:
移位寄存器源碼: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 翻轉周期,rst 持續時間,以及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

仿真結果如下:

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

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

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


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

小腳丫FPGA學習筆記.docx (572.01 KB, 下載次數: 22)


評分

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

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

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

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久草在线在线精品观看 | 成人免费区一区二区三区 | 综合婷婷 | 国产精品色 | 国产精品国产精品国产专区不卡 | 蜜桃精品视频在线 | 午夜久久 | 亚洲精品大全 | 一区二区不卡视频 | 日本精品一区二区三区在线观看视频 | 色啪网| 成人免费视频网站在线看 | 在线观看国产精品一区二区 | 日本一区二区三区在线观看 | 久久夜视频 | 国内精品久久久久久久 | 色一阁| 极品销魂美女一区二区 | 99re热精品视频国产免费 | 毛片入口 | 欧美a级成人淫片免费看 | 日韩精品一区二区三区久久 | 日韩精品免费一区二区在线观看 | 麻豆a级片| 亚洲欧美日韩一区 | 亚洲国产一区在线 | 国产极品车模吞精高潮呻吟 | 国产精品久久久久久久久久久久久久 | 婷婷丁香在线视频 | 九九热精品视频 | 一区二区激情 | 成人午夜免费福利视频 | 成人影院在线观看 | 亚洲v区 | 成人久久18免费网站麻豆 | 日韩国产一区二区三区 | 国产精品久久久久久一区二区三区 | 国内精品久久久久久久影视简单 | 久久精品一| 日韩欧美一级片 | 久久精品国产亚洲一区二区 |