日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

FPGA杂记5——格雷码转换设计

發布時間:2023/12/20 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 FPGA杂记5——格雷码转换设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在此感謝 特權同學,接下來寫到的FPGA雜記基本上源于他的B站講解視頻,同時這是他的淘寶商鋪鏈接,感興趣的同學也可以在B站中看到他更多的一些視頻學習資料,一起學習一起成長

1. 顯示和監視任務

1.1 顯示任務 $display 以及 $write

兩者的語法結構大概都是:任務名(“可選字符串+格式”,信號列表)

  • 任務名包括$displayb(二進制)、 $displayh(十六進制)、 $displayo(八進制)以及 $write的其他任務名
  • 可選字符串+格式包括%h(16進制輸出)、%c(ASCII輸出)、%b(二進制輸出)、%s(字符串輸出)、%t(以當前時間格式輸出顯示)等等
  • display和write的區別在于display輸出后會自動換行

%0d,加個0會使得輸出的數據前面的零或者空格刪掉(一般發生在輸出要求位數大于實際輸出位數的情況下)例如,32位的數據以十進制顯示為65,用顯示任務不加0的結果是:____(空格)65,但若是要求為%0d,那么輸出結果就是65

1.2 監視任務$monitor

$monitor任務在聲明后默認開啟,只有在其運行期間調用系統任務 $monitoroff 則會關閉監視任務知道系統再次調用系統任務 $monitoron后將重新開啟監視

以上兩種主要在testbench中調用任務,方便在測試中驗證自己的設計、邏輯功能的實現

2. 4位格雷碼計數器設計

2.1 設計實現

設計目標:以1S為一個計數周期(注意不是系統時鐘),計數值從0一直往上疊加,并將計數值不斷轉換成格雷碼輸出

`timescale 1ns/1ps module vlg_design(input i_clk, //時鐘為50MHz,20nsinput i_rst_n,output[3:0] o_gray); / //1s定時計數 localparam TIMER_1S_MAX_CNT = 32'd1_000_000_000/20; //50MHZ的時鐘在1s內的最大周期數,1S標志位reg[31:0] r_cnt;always @(posedge i_clk)if(!i_rst_n) r_cnt <= 'b0;else if(r_cnt < (TIMER_1S_MAX_CNT - 1)) r_cnt <= r_cnt + 'b1;else r_cnt <= 'b0;// //1s計數器 reg[3:0] r_second;always @(posedge i_clk)if(!i_rst_n) r_second <= 'b0;else if(r_cnt == (TIMER_1S_MAX_CNT-1)) r_second <= r_second + 'b1;else ;/ //r_second譯碼為格雷碼輸出 reg[3:0] r_gray;always @(posedge i_clk) if(!i_rst_n) r_gray <= 'b0;else begincase(r_second)4'b0000: r_gray <= 4'b0000;4'b0001: r_gray <= 4'b0001;4'b0010: r_gray <= 4'b0011;4'b0011: r_gray <= 4'b0010;4'b0100: r_gray <= 4'b0110;4'b0101: r_gray <= 4'b0111;4'b0110: r_gray <= 4'b0101;4'b0111: r_gray <= 4'b0100;4'b1000: r_gray <= 4'b1100;4'b1001: r_gray <= 4'b1101;4'b1010: r_gray <= 4'b1111;4'b1011: r_gray <= 4'b1110;4'b1100: r_gray <= 4'b1010;4'b1101: r_gray <= 4'b1011;4'b1110: r_gray <= 4'b1001;4'b1111: r_gray <= 4'b1000;default: ;endcase endassign o_gray = r_gray; endmodule

看整個運行過程,各部分都會定義一個寄存器暫時儲存輸出結果,最后再進行賦值操作

2.2 測試腳本testbench

`timescale 1ns/1ps module testbench_top(); //參數定義 `define CLK_PERIORD 20 //時鐘周期設置為20ns(50MHz) //接口申明 reg clk; reg rst_n; wire[3:0] o_gray; //對被測試的設計進行例化 vlg_design uut_vlg_design(.i_clk(clk),.i_rst_n(rst_n),.o_gray(o_gray)); //復位和時鐘產生 //時鐘和復位初始化、復位產生 initial beginclk <= 0;rst_n <= 0;#1000;rst_n <= 1; end//時鐘產生 always #(`CLK_PERIORD/2) clk = ~clk; //測試激勵產生 integer i; initial begin@(posedge rst_n); //等待復位完成$monitor("o_gray is %b at %0dns",o_gray,$time);$stop; endendmodule

2.3 測試結果

3. 基于查找表的8位格雷碼轉換

3.1 查找表LUT

查找表是相當于預先存儲好結果的數據表,免去了運算過程,從另外一種角度來說相當于ROM。我們接下來利用IP的ROM加入查找表,通過VIVADO創建出ROM的初始化COE文件用于存放LUT的數據

3.2 ROM初始化COE文件

COE文件用于對ROM作初始化賦值,具體格式如下

memory_initialization_radix = 位數(數據格式);memory_initialization_vector = 初始化數據; //查找表數據

COE文件制作以及使用ROM流程:

  • 打開vivado工程文件點擊IP Catalog選擇生成ROM(以Block Memory Generator為例)
  • 將打開的ROM的Memory Type改成Single Port ROM
  • Port A Options里面將位寬與數據個數改成相應的數據,同時使能always
  • Other Options中導入COE文件,這里由于沒有COE文件可以在線創建一個即可
  • 然后點擊OK會彈出一個generate的窗口直接生成即可
  • 回到vivado界面的Sources里面的IP Sources中查看你所配置IP的Instantiation Template中的原語 .veo 文件,并將原語用于你所設計的verilog代碼中

這里要注意一下,只要在IP中勾選了Primitives Output Register,那么就意味著你會延時兩個時鐘周期輸出數據,在Summary中也可查看

3.3 設計代碼.v

`timescale 1ns/1ps module vlg_design(input i_clk, input i_rst_n,input i_en,input[7:0] i_data,output o_vld, //有效信號output[7:0] o_gray);// //o_vld是i_en兩個時鐘周期的延時 reg[1:0] r_vld;always@(posedge i_clk)if(!i_rst_n) r_vld <= 'b00;else r_vld <= {r_vld[0],i_en};assign o_vld = r_vld[1];//IP ROM_LUT blk_mem_gen_0 uut_blk_mem_gen_0 (.clka(i_clk), // input wire clka.addra(i_data), // input wire [7 : 0] addra.douta(o_gray) // output wire [7 : 0] douta ); endmodule

3.4 測試腳本

`timescale 1ns/1ps module testbench_top(); //參數定義 `define CLK_PERIORD 20 //時鐘周期設置為20ns(50MHz) //接口申明 reg clk; reg rst_n; reg i_en; reg[7:0] i_data; wire o_vld; wire[7:0] o_gray; //對被測試的設計進行例化 vlg_design uut_vlg_design(.i_clk(clk),.i_rst_n(rst_n),.i_en(i_en),.i_data(i_data),.o_vld(o_vld),.o_gray(o_gray)); //復位和時鐘產生 //時鐘和復位初始化、復位產生 initial beginclk <= 0;rst_n <= 0;#1000;rst_n <= 1; end //時鐘產生 always #(`CLK_PERIORD/2) clk = ~clk; //測試激勵產生 initial begini_en <= 'b0;i_data <= 'b0;@(posedge rst_n); //等待復位完成@(posedge clk);i_en <= 'b1;i_data <= 'b0;@(posedge clk);repeat(255) begin //循環疊加256次i_data <= i_data + 1;@(posedge clk);endi_en <= 'b0;i_data <= 'b0;#1000;$stop; end// //實時顯示 always@(posedge clk) beginif(o_vld) $display("%b",o_gray);else ; endendmodule

4. 格雷碼轉換的快速算法

4.1 算法介紹

  • 二進制碼(自然數)的最高位是MSB,最低位是0
  • 二進制碼的MSB位直接賦值給格雷碼的MSB位
  • 對于次高位(MSB-1)位到最低位0,使用二進制碼相鄰位異或的方式獲取格雷碼
    • 若二進制碼字的第i位與第i+1位相同,則第 i 位的格雷碼為0
    • 若二進制碼字的第i位與第i+1位不同,則第 i 位的格雷碼為1

舉個例子:4位的二進制碼1010轉換格雷碼(不通過LUT,直接通過RTL實現)

位數操作按位輸出格雷碼
Bit3取MSB位1
Bit21 xor 01
Bit10 xor 11
Bit01 xor 01

最終輸出結果:1111

4.2 模塊設計

`timescale 1ns/1ps module vlg_design #(parameter MSB = 7) //參數定義(input i_clk,input i_rst_n,input i_en,input[MSB:0] i_data,output reg o_vld,output reg[MSB:0] o_gray);always @(posedge i_clk) if(!i_rst_n) o_vld <= 'b0;else o_vld <= i_en; //快速轉換設計 always @(posedge i_clk)o_gray[MSB] <= i_data[MSB];genvar i; generatefor(i=MSB-1;i>=0;i=i-1) beginalways @(posedge i_clk) begino_gray[i] <= i_data[i] ^ i_data[i+1];endend endgenerateendmodule

4.3 測試腳本

`timescale 1ns/1ps module testbench_top(); //參數定義 `define CLK_PERIORD 10 //時鐘周期設置為10ns(100MHz) parameter GRAY_MSB = 7; //定義參數 //接口申明 reg clk; reg rst_n; reg i_en; reg[GRAY_MSB:0] i_data; wire o_vld; wire[GRAY_MSB:0] o_gray; //對被測試的設計進行例化 vlg_design #(.MSB(GRAY_MSB))uut_vlg_design(.i_clk(clk),.i_rst_n(rst_n),.i_en(i_en),.i_data(i_data),.o_vld(o_vld),.o_gray(o_gray)); //復位和時鐘產生 //時鐘和復位初始化、復位產生 initial beginclk <= 0;rst_n <= 0;#1000;rst_n <= 1; end //時鐘產生 always #(`CLK_PERIORD/2) clk = ~clk; //測試激勵產生 initial begini_en <= 'b0;i_data <= 'b0;$display("The value of GRAY_MSB is %0d",GRAY_MSB); @(posedge rst_n); //等待復位完成@(posedge clk);i_en <= 'b1;i_data <= 'b0;repeat(2**(GRAY_MSB+1)-1) begin //一共有(MSB+1)位,相當于計數值最大為2^(MSB+1)-1@(posedge clk);i_en <= 'b1;i_data <= i_data + 1;end@(posedge clk);i_en <='b0;$stop; endalways @(posedge clk)if(o_vld) $display("%b",o_gray);else ;endmodule

4.4 測試結果

腳本顯示(modelsim):
測試波形:

總結

以上是生活随笔為你收集整理的FPGA杂记5——格雷码转换设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 69免费视频| japanese国产 | 欧美一区二区视频在线观看 | 91丨九色丨蝌蚪丨丝袜 | 香蕉精品视频在线观看 | 香港三级在线视频 | 日本伦理片在线播放 | 四虎精品一区二区三区 | 一级免费黄色片 | 很色的网站 | 欧美另类综合 | 国产区网址 | 日日碰狠狠添天天爽无码 | 日日摸天天爽天天爽视频 | 日本精品视频一区 | 中文字幕乱码亚洲精品一区 | 成人导航网站 | 国产精品丝袜 | 日韩一区三区 | 日本黄区免费视频观看 | 精品免费视频一区二区 | 波波野结衣| 成人av片免费看 | 青娱乐av在线 | aaa国产精品 | 性——交——性——乱免费的 | 九九国产视频 | 久久久久国产视频 | 久久精品综合网 | 久久99热久久99精品 | 色开心| 国产超碰人人模人人爽人人添 | 欧美综合视频在线观看 | 91直接进入 | 亚欧视频在线观看 | av爽妇网| 久草资源在线 | 国产精品传媒在线观看 | 激情网久久| 激情久久久久久 | 国产原创av在线 | 日本亚洲最大的色成网站www | 久久久久久久久久久久国产 | 中文字幕不卡av | 中文字幕一区二区三区四区视频 | 欧美日韩一区二区三区在线电影 | 极品少妇在线 | 欧美高清日韩 | 在线观看欧美一区二区三区 | 久久国产柳州莫菁门 | 欧美wwwxxxx| www久久精品| 人人干网站 | 爱爱91| 男生女生羞羞网站 | 国产电影一区二区三区 | 污漫在线观看 | www三级| 欧美一区二区三区免费 | 男人视频网 | 美女网站污 | 国产51自产区 | 37p粉嫩大胆色噜噜噜 | 中文字幕在线观看免费高清 | 国产精品88 | 最新成人 | 日韩av大全 | 午夜精品一区二区在线观看 | 91福利区| www.日批 | 人妻熟女aⅴ一区二区三区汇编 | 国产精品第一 | 超碰在线国产97 | 天天操天天看 | 一区二区三区久久 | 日本爽爽爽爽爽爽在线观看免 | 超碰国产一区二区三区 | 欧美久久久久久又粗又大 | 日本网站在线 | 成人免费网站视频 | 欧美成人精精品一区二区频 | 日韩一区二区毛片 | jizz色| 国产精品久久久久久久专区 | 黑白配av| 国产成人三级一区二区在线观看一 | 有码在线视频 | 黄色成人av在线 | 久久国产精品一区 | 国产v综合v亚洲欧美久久 | 日韩一区在线观看视频 | 国产美女主播在线 | 爱爱的免费视频 | 午夜寂寞院 | 美女高潮黄又色高清视频免费 | 欧美黄网在线观看 | 亚洲精品性 | 性色av一区二区 | 成人av一区二区三区 |