基于FPGA 的8b10b编解码电路前端电路设计
基于FPGA 的8b10b編解碼電路前端電路設(shè)計(jì)
摘 要
本設(shè)計(jì)是采用EDA技術(shù)設(shè)計(jì)的一種8B /10B 編解碼電路,實(shí)現(xiàn)了在高速的串行數(shù)據(jù)傳輸中的直流平衡。該編解碼電路設(shè)計(jì)大體上可以由五個(gè)模塊構(gòu)成,分別是默認(rèn)編碼模塊、差異度計(jì)算模塊、編碼校正模塊、并串轉(zhuǎn)換模塊、顯示模塊。
采用Verilog HDL 描述語(yǔ)言進(jìn)行電路的設(shè)計(jì)、使用modelsim 10.2a 進(jìn)行功能仿真、在通過Quartus II 13.1 進(jìn)行FPGA邏輯綜合和適配下載,并在Alter 公司的Cyclone IV E 的芯片EP4CE6F17C8 上實(shí)現(xiàn)并完成測(cè)試,最后用tcl語(yǔ)言編寫約束腳本和啟動(dòng)文件,通過Synopsys的“Design Compiler”進(jìn)行邏輯綜合。
關(guān)鍵詞: FPGA;Verilog HDL;8B10B編解碼;tcl;邏輯綜合。
前 言
可編程的“萬能芯片” FPGA(Field-Programmable Gate Array)——現(xiàn)場(chǎng)可編程門陣列,是指一切通過軟件手段更改、配置器件內(nèi)部連接結(jié)構(gòu)和邏輯單元,完成既定設(shè)計(jì)功能的數(shù)字集成電路。
FPGA可以實(shí)現(xiàn)怎樣的能力,主要取決于它所提供的門電路的規(guī)模。如果門電路的規(guī)模足夠大,FPGA通過編程可以實(shí)現(xiàn)任意芯片的邏輯功能,例如ASIC、DSP甚至PC處理器等。這就是FPGA為什么被稱之為“萬能芯片”的原因。
以硬件描述語(yǔ)言(Verilog或VHDL)所完成的電路設(shè)計(jì),可以經(jīng)過簡(jiǎn)單的綜合與布局,快速的燒錄至 FPGA 上進(jìn)行測(cè)試,是現(xiàn)代 IC設(shè)計(jì)驗(yàn)證的技術(shù)主流。這些可編輯元件可以被用來實(shí)現(xiàn)一些基本的邏輯門電路。在大多數(shù)的FPGA里面,這些可編輯的元件里也包含記憶元件例如觸發(fā)器(Flip-flop)或者其他更加完整的記憶塊。
FPGA的核心具有可編程靈活性高、開發(fā)周期短、并行計(jì)算可編程靈活性高等優(yōu)點(diǎn)。系統(tǒng)設(shè)計(jì)師可以根據(jù)需要通過可編輯的連接把FPGA內(nèi)部的邏輯塊連接起來,就好像一個(gè)電路試驗(yàn)板被放在了一個(gè)芯片里。一個(gè)出廠后的成品FPGA的邏輯塊和連接可以按照設(shè)計(jì)者而改變,所以FPGA可以完成所需要的邏輯功能。
1總體電路結(jié)構(gòu)設(shè)計(jì)
1.1 基本原理
在高速的串行數(shù)據(jù)傳輸中 ,傳送的數(shù)據(jù)被編碼 成自同步的數(shù)據(jù)流 ,就是將數(shù)據(jù)和時(shí)鐘組合成單一 的信號(hào)進(jìn)行傳送 ,使得接收方能容易準(zhǔn)確地將數(shù)據(jù) 和時(shí)鐘分離 ,而且要達(dá)到令人滿意的誤碼率 ,其關(guān)鍵 技術(shù)在于串行傳輸中數(shù)據(jù)的編碼方法。目前大多數(shù)高速串行標(biāo)準(zhǔn)都采用 8B /10B 編碼方案 ,例如光纖 通道 1、PCI - Exp ress、串行 ATA、以太網(wǎng)、XAU I、In2 finiBand和串行相連 SCSI等。使用 8B /10B編碼技 術(shù) ,較好地解決了以下問題。
(1)轉(zhuǎn)換密度 :保證數(shù)據(jù)流中有足夠的信號(hào)轉(zhuǎn) 換。采用 8B /10B編碼方法 ,數(shù)據(jù)流中連續(xù)的“1”或 連續(xù)的“0”不超過 5個(gè) ,使接收端鎖相環(huán) (PLL)能正 常工作 ,避免接收端時(shí)鐘漂移或同步丟失而引起數(shù) 據(jù)丟失。
(2) DC補(bǔ)償 : 在高速的數(shù)據(jù)傳輸線路中 ,一般 采用差分信號(hào) ,需要直流分量盡量小 ,而 8B /10B有 DC補(bǔ)償功能 ,即鏈路中不會(huì)隨著時(shí)間推移而出現(xiàn) DC偏移。
(3)檢錯(cuò) : 8B /10B編碼采用冗余方式 ,將 8位 的數(shù)據(jù)和一些特殊字符按照特定的規(guī)則編碼成 10 位的數(shù)據(jù) ,根據(jù)這些規(guī)則 ,能檢測(cè)出傳輸過程中發(fā)生 錯(cuò)誤的信息。
(4)特殊字符 : 8B /10B編碼規(guī)定了一些特殊字符 ,可用作幀同步字符和其他的分隔符或控制字符。
8B/10B,也叫做8字節(jié)/10字節(jié)或8B10B。8B/10B方式最初由IBM公司于1983年發(fā)明并應(yīng)用于ESCON(200M互連系統(tǒng)),由Al Widmer和Peter Franaszek在IBM的刊物“研究與開發(fā)”上描述。把 8位數(shù)據(jù)字節(jié)轉(zhuǎn)換成串行傳輸使用的 10位碼。8B /10B編碼 保證了 1和 0的相對(duì)平衡組合 ,而與數(shù)據(jù)值無關(guān) ,簡(jiǎn) 化了時(shí)鐘恢復(fù) ,降低了接收機(jī)成本。編碼提供的其它位還促進(jìn)了誤碼檢測(cè)。8B /10B編碼提供了構(gòu)建串行通信使用的一套基礎(chǔ)數(shù)據(jù)和控制字符。許多獨(dú)立標(biāo)準(zhǔn)都以這個(gè)公共字符集為基礎(chǔ) ,定義更高的協(xié)議層。
1.2 電路總體圖
1.3 電路功能框圖
1.4 電路接口表
1.5 驗(yàn)證方案
為了驗(yàn)證編解碼數(shù)據(jù)的正確性,首先在modelsim中仿真,通過觀察信號(hào)的時(shí)序波形來對(duì)照真值表驗(yàn)證,在邏輯層面仿真成功后,再通過quartus II將各個(gè)模塊燒錄開發(fā)板,通過顯示模塊,將數(shù)據(jù)通過數(shù)碼管顯示出來進(jìn)而進(jìn)行驗(yàn)證數(shù)據(jù)的正確性,其中編碼的數(shù)據(jù)來源于開發(fā)板上面的按鍵輸入,解碼的數(shù)據(jù)來源于編碼數(shù)據(jù)的結(jié)果。
經(jīng)過開發(fā)板的下載驗(yàn)證,通過結(jié)果分析可知,本方案符合課設(shè)設(shè)計(jì)任務(wù)書的要求,具有一定的可行性。
2模塊設(shè)計(jì)
本設(shè)計(jì)按功能大體上可以分為8個(gè)子模塊,分別為默認(rèn)編碼模塊、差異度運(yùn)算模塊、編碼校驗(yàn)?zāi)K、解碼模塊、并串轉(zhuǎn)換模塊、消抖模塊、輸入模塊和顯示模塊。
2.1 默認(rèn)編碼模塊設(shè)計(jì)
8b/10b編碼是將一組連續(xù)的8位數(shù)據(jù)分解成兩組數(shù)據(jù),一組3位,一組5位,經(jīng)過編碼后分別成為一組4位的代碼和一組6位的代碼,從而組成一組10位的數(shù)據(jù)發(fā)送出去。相反,解碼是將1組10位的輸入數(shù)據(jù)經(jīng)過變換得到8位數(shù)據(jù)位。
數(shù)據(jù)值可以統(tǒng)一的表示為DX.Y或KX.Y,其中D表示為數(shù)據(jù)代碼,K表示為特殊的命令代碼,X表示輸入的原始數(shù)據(jù)的低5位EDCBA,Y 表示輸入的原始數(shù)據(jù)的高3位HGF。
3B/4B 和 5B/6B 是通過映射機(jī)制進(jìn)行編碼的,這種映射機(jī)制已經(jīng)標(biāo)準(zhǔn)化成相應(yīng)的映射表
根據(jù)表格我們可以看出:5b/6b 編碼的值可能有一種,還可能有兩種。如果是前者,那么6b中的“1”的數(shù)量和“0” 的數(shù)量一定是相等的,如果是后者,那么編碼6b的第兩種情況為按位取反的結(jié)果。
所以,在進(jìn)行編碼過程中,先對(duì)5b/6b 進(jìn)行默認(rèn)編碼,如果是第一種情況(即1的數(shù)量和0的數(shù)量相同),就在6b的最高位添加一個(gè)標(biāo)記位,并且用0進(jìn)行標(biāo)記,否則(1的數(shù)量比0的數(shù)量多),就用1最為標(biāo)記。3b/4b 默認(rèn)編碼過程與之相似,需要注意的是當(dāng)3b=111時(shí),有兩組編碼結(jié)果,為了避免10b的結(jié)果中0或1的數(shù)量連續(xù)超過4個(gè)的情況,4b碼1000 和0111 這組編碼出現(xiàn)的特殊情況外,其它的編碼規(guī)則同上面分析的3B 碼具有雙值編碼的情況,此時(shí)的編碼取0001 和1110 這組編碼。
2.2 差異度運(yùn)算設(shè)計(jì)
8B/10B 編碼中有兩個(gè)重要的概念,不均等性( disparity )和極性偏差( runningdisparity , RD)。前者表示‘ 1’和‘ 0’個(gè)數(shù)的差值,其有如下規(guī)律:
(1)若 ABCDE 的 Disparity 值為 - 1, 那么在‘ RD- ’項(xiàng)中生成的 abcde 與 ABCDE 有一一對(duì)應(yīng)的關(guān)系 , 并且 i=‘1’ , 此時(shí)除 ABCDE= ‘00011’外 abcde i 是唯一的 ;
(2)若 ABCDE 的 Disparity 值為 + 1, 那么在‘ RD-’項(xiàng)中生成的 abcde 與 ABCDE 有一一對(duì)應(yīng)的關(guān)系 , 并且 i=‘0’, 此時(shí)除 ABCDE = ‘ 11100’外 abcdei 是唯一的 ;
(3)若 ABCDE 的 Disparity 值為 + 3, 那么在‘ RD-’項(xiàng)中生成的 abcde 與 ABCDE 有一一對(duì)應(yīng)的關(guān)系 , 并且 i=‘0’, 此時(shí) abcdei 是互為反碼的兩個(gè)值 ;
(4)若 ABCDE 的 Disparity 為其他值 , 此時(shí) abcde i 具有互為反碼的兩個(gè)值 , 對(duì)這些特殊的‘RD –’項(xiàng)中的值可直接用查表法實(shí)現(xiàn)。
后者的取值分為以下三種:
(1)當(dāng)碼字中‘ 1’比‘ 0’多 , 或者 4B 碼為 1100,或者 6B 碼為 111000 時(shí), 該碼字被定義為正極性碼 ,這個(gè)時(shí)候 RD 取正 ;
(2)當(dāng)碼字中‘ 1’比‘ 0’少 , 或者 4B 碼為 0011,或者 6B 碼為 000111 時(shí), 該碼字被定義為負(fù)極性碼 , 這個(gè)時(shí)候 RD 取負(fù) ;
(3)其他碼字定義為中性碼 , RD 取其前一碼字的 RD 游程值。
2.3 編碼校驗(yàn)?zāi)K設(shè)計(jì)
在3b4b默認(rèn)編碼模塊中,編碼產(chǎn)生的數(shù)據(jù)大致有兩種情況,“0”和“1”的數(shù)量相等,或者“0”和“1”的數(shù)量不等,這兩種情況和上一次數(shù)據(jù)的RD值組合產(chǎn)生幾種結(jié)果:
為了方便判斷各個(gè)狀態(tài)的邏輯情況,將4b數(shù)據(jù)中1的個(gè)數(shù)多的情況標(biāo)記為1,否則為0,6b數(shù)據(jù)同理。
2.4 解碼模塊設(shè)計(jì)
為得到快的解碼處理速度 , 電路設(shè)計(jì)中采用數(shù)據(jù)解碼并行處理完成, 而由數(shù)據(jù) 選擇器控制選擇輸出數(shù)據(jù)的拓?fù)浣Y(jié)構(gòu)來實(shí)現(xiàn) 。8B /10B編碼電路的原理是對(duì) 8B 數(shù)據(jù)編碼時(shí) 將數(shù)據(jù)分為高 3位和低 5位兩部分 , 分別進(jìn)行 3B / 4B編碼和 5B /6B編碼結(jié)合在一起而生成最終的 10B數(shù)據(jù) 。 8B /10B數(shù)據(jù)解碼電路 , 分為 3B /4B 解 碼電路和 5B /6B解碼電路兩個(gè)部分, 共同實(shí)現(xiàn)解碼 的完整數(shù)據(jù)解碼。
由于解碼不需要考慮差異度RD的值,從10bit 到 8bit ,所以解碼的數(shù)據(jù)具有一一對(duì)應(yīng)關(guān)系,可以通過4b到3b、6b到5b 直接查表來實(shí)現(xiàn)。可以參照附錄I。
其中,需要注意的是,10bit是解碼原始數(shù)據(jù)一共有2^10 1024種情況,但是與其對(duì)應(yīng)的8bit的編碼只有2^8 256種結(jié)果,這樣如果解碼的原始數(shù)據(jù) 10bit 不在編碼產(chǎn)生的范圍內(nèi),則需要解出一個(gè)錯(cuò)誤標(biāo)志信息,產(chǎn)生8bit 的數(shù)據(jù)為設(shè)定的默認(rèn)值。
2.5 消抖模塊設(shè)計(jì)
消抖模塊主要的核心是對(duì)可能產(chǎn)生的按鍵信號(hào)進(jìn)行判斷是否是外部按鍵輸 入而不是內(nèi)部電平波動(dòng)。一旦電平波動(dòng)則開始計(jì)數(shù),因?yàn)槭褂冒存I消抖時(shí)間為 20ms,實(shí)際消抖時(shí)間 20—40ms。 消抖只考慮的按鍵按下的抖動(dòng),忽略按鍵上彈的電平抖動(dòng),因?yàn)檫@段抖動(dòng)不影響電路的功能和性能,如圖為消抖模塊內(nèi)部接口波形圖:
一旦檢測(cè)到 KEY_IN 按鍵電平發(fā)生波動(dòng),為 0 開始計(jì)數(shù),為 1 清除計(jì)數(shù)值,
當(dāng)電平穩(wěn)定為0時(shí)才能完成一次穩(wěn)定計(jì)數(shù)到4000,產(chǎn)生消抖后的按鍵信號(hào)KEY。 而維持按鍵長(zhǎng)時(shí)間不抬起,KEY 也一直為 0 不變。當(dāng)按鍵 KEY_IN 抬起時(shí),盡管 按鍵任然會(huì)產(chǎn)生電平波動(dòng),但是 KEY 信號(hào)穩(wěn)定拉高為 1,這樣完成一次消抖 同步到本地時(shí)鐘的過程。下面列出消抖模塊的端口信號(hào)表:
2.6 并串轉(zhuǎn)換模塊
由于傳輸中所用的是串行的數(shù)據(jù)流,所以,編碼完成后需要將編號(hào)的并行10bit結(jié)果轉(zhuǎn)換成串行的10bit,才能進(jìn)行數(shù)據(jù)傳輸。
同理,在解碼過程之前,也需要將串行的10bit轉(zhuǎn)換成并行的以便于解碼。
并行轉(zhuǎn)換的數(shù)據(jù)為10bit,通過一個(gè)十進(jìn)制的計(jì)數(shù)器進(jìn)行控制,當(dāng)計(jì)數(shù)值為0的時(shí)候,mask打開,并行數(shù)據(jù)送入移位寄存器中,并把最低位的一比特?cái)?shù)據(jù)送出串行輸出口。當(dāng)計(jì)數(shù)值為非零時(shí),mask選通前一個(gè)D觸發(fā)器的輸出,一個(gè)時(shí)鐘上升沿,將數(shù)據(jù)向右移動(dòng)移位,將數(shù)據(jù)送到串行輸出端。
2.7 輸入模塊設(shè)計(jì)
本模塊需要提供給FPGA的功能模塊需要編碼的8bit原始數(shù)據(jù),這樣整個(gè)系統(tǒng)才能運(yùn)行,開發(fā)板上面可以利用的資源為四個(gè)物理按鍵,其中系統(tǒng)復(fù)位rstn占用一個(gè),所以可以供用戶自定義的按鍵有三個(gè),本模塊需要通過3個(gè)按鍵輸入需要驗(yàn)證的8bit 并行數(shù)據(jù)。
本模塊一共設(shè)計(jì)了三種工作模式,分別為計(jì)數(shù)輸入模式、按鍵輸入模式和隨機(jī)模式。計(jì)數(shù)輸入模式:通過按鍵控制輸入的8bit數(shù)據(jù)逐次加一,這樣可以編碼出順序的相鄰數(shù)據(jù)。按鍵輸入模式:通過兩個(gè)按鍵控制,key1控制8bit的高4位,key2控制8bit的低4位,對(duì)key3的下降沿進(jìn)行計(jì)數(shù),即可指定輸入數(shù)據(jù)的值。隨機(jī)模式:通過一個(gè)key2按鍵進(jìn)行輸入,當(dāng)檢測(cè)到key2位低電平的時(shí)候,對(duì)計(jì)數(shù)變量cnt進(jìn)行循環(huán)加一操作,計(jì)數(shù)變量cnt為8bit,最后將cnt的值通過持續(xù)賦值給輸入,這樣每當(dāng)key2松開的時(shí)候,可以認(rèn)為輸入的數(shù)據(jù)為一個(gè)隨機(jī)的值。
2.8 顯示模塊設(shè)計(jì)
本次使用的FPGA開發(fā)板上面的數(shù)碼管為6個(gè)8段數(shù)碼管,并且通過sel信號(hào)進(jìn)行選通,drv信號(hào)輸入顯示編碼數(shù)據(jù)。由于所有是數(shù)碼管并聯(lián)在一起,若想在不同的數(shù)碼管上面顯示不同的數(shù)據(jù),需要分時(shí)復(fù)用數(shù)碼管,首先對(duì)開發(fā)板上面的50M時(shí)鐘進(jìn)行分頻,用分好頻率的時(shí)鐘進(jìn)行移位和選通操作。
數(shù)值0—F分別譯碼成用于數(shù)碼管顯示的8bit顯示碼,分共陽(yáng)和共陰的區(qū)別譯碼不同,需要根據(jù)不同的 FPGA 開發(fā)板來確定。八段數(shù)碼管分別為 A,B,C,D,E,F,G,DP八段,前七段用于顯示數(shù)字以及字母等字符,DP段在數(shù)碼管上右下角,點(diǎn)亮后為小數(shù)點(diǎn)。對(duì)于多個(gè)數(shù)碼管同一時(shí)刻只能點(diǎn)亮一個(gè)數(shù)碼管。如圖2.8所示:
由于本設(shè)計(jì)使用的FPGA開發(fā)板的數(shù)碼管顯示是采用的是共陽(yáng)極數(shù)碼管,且是六個(gè)并聯(lián)的獨(dú)立數(shù)碼管,有6個(gè)數(shù)碼管選通引腳,在這個(gè)設(shè)計(jì)中只需要四個(gè)數(shù)碼管即可,現(xiàn)在列出共陽(yáng)八段極數(shù)碼管的顯示碼:
除了以上16個(gè)對(duì)應(yīng)的顯示碼外,額外還有一個(gè)特殊的現(xiàn)實(shí),僅僅用于電路復(fù)位是數(shù)碼管上的現(xiàn)實(shí),數(shù)碼管僅g段點(diǎn)亮,其顯示碼為10111111。
需要顯示的數(shù)據(jù)有編碼輸入的數(shù)據(jù)、編碼產(chǎn)生的輸出數(shù)據(jù)、解碼的數(shù)據(jù),所以6個(gè)數(shù)碼管顯示資源有些不足,這里采用了數(shù)碼管動(dòng)態(tài)游動(dòng)顯示的方式實(shí)現(xiàn),定義一個(gè)選通信號(hào),通過控制這個(gè)信號(hào)使數(shù)據(jù)中第一個(gè)4bit的位置的數(shù)碼管熄滅,這樣數(shù)據(jù)游走的同時(shí),可以明顯看出數(shù)據(jù)串的第一位,這樣一來,就實(shí)現(xiàn)了數(shù)碼管的高效率復(fù)用。
三 設(shè)計(jì)約束與邏輯綜合
3.1設(shè)計(jì)約束
這里需要使用design compiler工具,可以參考design compiler使用教程
3.1.1約束策略
對(duì)于一個(gè)由時(shí)鐘控制的數(shù)字邏輯電路來說,時(shí)序是最為重要的。encode_decode_top.v是本設(shè)計(jì)所要約束的文件。本設(shè)計(jì)定的時(shí)鐘CLK的頻率為50MHZ,即周期為20ns。輸入為key[3:0],輸出為led_sel[5:0]和led_drv[7:0],他們都是由CLK信號(hào)同步控制,所以這些信號(hào)延時(shí)約占時(shí)鐘信號(hào)的35%,即輸入輸出延時(shí)設(shè)置為7ns。本次對(duì)此電路的綜合約束需要分為以下幾部分:對(duì)CLK時(shí)鐘信號(hào)進(jìn)行設(shè)置,對(duì)每個(gè)輸入輸出信號(hào)的約束,對(duì)扇出和驅(qū)動(dòng)負(fù)載能力能度需要進(jìn)行約束設(shè)置,最后輸出報(bào)告。
以上約束只有對(duì)本電路結(jié)構(gòu)非常熟悉才能對(duì)自己的時(shí)序約束更完善。
3.1.2 約束腳本
首先是讀入源代碼,也就是HDL文本描述的設(shè)計(jì)文件,此處不用制定目錄,Design Compiler會(huì)在搜索目錄中搜索。tcl語(yǔ)句如下:
read_verilog {encode_decode_top.v control_baud.v core_control.v decode_calculation.v running_disparity.v default_encode_3b_to_4b.v default_encode_5b_to_6b.v encode8b10b1.v encode_input_generate.v particular.v display2.v }
讀入設(shè)計(jì)原文件后,一般設(shè)定當(dāng)前設(shè)計(jì),這樣約束條件才可能有針對(duì)性的施加。tcl語(yǔ)句如下:
current_design encode_decode_top.v
設(shè)定當(dāng)前設(shè)計(jì)后,要完成鏈接,也就是將設(shè)計(jì)與庫(kù)鏈接起來,用于映射過程中搜索相應(yīng)的單元,完成綜合。tcl語(yǔ)句如下:
Link
檢查設(shè)計(jì),主要完成檢查轉(zhuǎn)換的設(shè)計(jì)。tcl語(yǔ)句如下:
check_design
然后對(duì)設(shè)計(jì)設(shè)定時(shí)序約束,這是最重要的一項(xiàng)約束,用于設(shè)定設(shè)計(jì)的工作速度。針對(duì)不同的設(shè)計(jì)部分,有不同的約束方法。針對(duì)本次設(shè)計(jì),采用全同步,雙時(shí)鐘工作的實(shí)際情況。以下語(yǔ)句設(shè)定時(shí)鐘及屬性、輸入輸出信號(hào)時(shí)間余量。
設(shè)定名稱為original_clk的時(shí)鐘,由于采用50MHz的時(shí)鐘,故設(shè)定時(shí)鐘周期為20ns。
tcl語(yǔ)句如下:
create_clock [get_ports original_clk] -period 20 -waveform {10 20}
設(shè)定為理想時(shí)鐘不對(duì)時(shí)鐘網(wǎng)絡(luò)進(jìn)行驅(qū)動(dòng)從而在使得綜合工具在優(yōu)化階段
不去修改或移除該object,對(duì)時(shí)鐘設(shè)置dont_touch屬性,那么就可以避免在綜合優(yōu)化時(shí)對(duì)時(shí)鐘上插入 buffer。tcl語(yǔ)句如下:
set_dont_touch_network [get_clocks " original_clk"]
set_ideal_network [get_ports " original_clk "]
告訴綜合器不要對(duì)復(fù)位進(jìn)行驅(qū)動(dòng)。tcl語(yǔ)句如下:
set_dont_touch_network [get_ports rstn]
set_ideal_network [get_ports rstn]
設(shè)定輸入信號(hào)最大時(shí)間延時(shí)。tcl語(yǔ)句如下:
set_input_delay -clock original_clk -max 7 [get_ports key1]
set_input_delay -clock original_clk -max 7 [get_ports key2]
set_input_delay -clock original_clk -max 7 [get_ports key3]
設(shè)定輸出信號(hào)最大時(shí)間延時(shí)。tcl語(yǔ)句如下:
set_output_delay -clock original_clk -max 7 [get_ports {led_sel[5]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_sel[4]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_sel[3]}] set_output_delay -clock original_clk -max 7 [get_ports {led_sel[2]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_sel[1]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_sel[0]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_drv[7]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_drv[6]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_drv[5]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_drv[4]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_drv[3]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[2]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[1]}]
set_output_delay -clock original_clk -max 7 [get_ports {led_drv[0]}]
檢查時(shí)序。tcl語(yǔ)句如下:
check_timing
設(shè)定綜合的操作條件。tcl語(yǔ)句如下:
set_operating_conditions -max slow -max_library slow.db:slow\ -min fast -min_library fast.db:fast
設(shè)定線負(fù)載模型,本設(shè)計(jì)選擇tsmc18_wl20模型。tcl語(yǔ)句如下:
set_wire_load_model -name tsmc18_wl20 -library slow.db:slow
設(shè)定輸出負(fù)載電容。tcl語(yǔ)句如下:
設(shè)定扇出最大負(fù)載能力。tcl語(yǔ)句如下:
set_max_fanout 20 [current_design]
驅(qū)動(dòng)能力設(shè)定。tcl語(yǔ)句如下:
設(shè)定輸出網(wǎng)表的格式規(guī)則,以消除gate level nelist中的assign。tcl語(yǔ)句如下:
set verilogout_no_tri true
set_fix_multiple_port_nets -all -buffer_constants
最大能力進(jìn)行綜合。tcl語(yǔ)句如下:
compile -map high
輸出時(shí)序報(bào)告。tcl語(yǔ)句如下:
rc > log/rc.log
輸出網(wǎng)表。tcl語(yǔ)句如下:
write -f verilog -hier -o encode_decode.v
輸出綜合數(shù)據(jù)文件。tcl語(yǔ)句如下:
write -f ddc -hier -o encode_decode.ddc
輸出延時(shí)文件。tcl語(yǔ)句如下:
write_sdf encode_decode.sdf
輸出scl命令文件,在file>Save Info輸出encode_decode.dc,文件中將會(huì)完整的包含所有tcl約束命令和各種環(huán)境、線載配置等。
除了以上報(bào)告外,還應(yīng)該輸出編譯后對(duì)整個(gè)設(shè)計(jì)的各個(gè)方面的報(bào)告文件,如Report_area、Report_cells、Report_clock_skew、Report_constraints、Report_design、Report_nets、Report_path_group、Report_ports、Report_power、Report_reference、Report_timing_paths、Report_timing_requirements、 Report_wire_load等報(bào)告文件。
3.2邏輯綜合
3.2.1 綜合文件
首先在家目錄(home)下建立 home/victor/dclab 作為本次實(shí)驗(yàn) dc 的操作主目錄。在 dclab 目錄下,建立設(shè)計(jì)存放目錄如 rtl/code、約束文件目錄如 constraints、輸出網(wǎng)表文件目錄ntlist、報(bào)告輸出目錄report、文件目錄work
等等,在綜合前需要準(zhǔn)備以下幾類文件:
.synopsys_dc.setup文件即啟動(dòng)項(xiàng)文件:
在這個(gè)文件中,需要將所用到的庫(kù)單元文件的路徑和電路設(shè)計(jì)文件所存放的路徑寫入,以便軟件在工作時(shí)能夠找到這些文件并正確識(shí)別,本設(shè)計(jì)將它存放在
work目錄下。主要配置libPath、Search_Path、Link_library、Target_library、
Symbol_library,本設(shè)計(jì).synopsys_dc.setup文件具體配置見附錄B。
*.v文件:
本設(shè)計(jì)為 8b10b編解碼電路,有如下文件 encode_decode_top.v control_baud.v core_control.v encode8b10b1.v decode_calculation.v running_disparity.v encode_input_generate.v default_encode_3b_to_4b.v default_encode_5b_to_6b.v display2.v particular.v
本設(shè)計(jì)所使用電路描述語(yǔ)言為verilog HDL語(yǔ)言,所以需要將功能電路的設(shè)計(jì)文件準(zhǔn)備好以便用于約束綜合,這些文件應(yīng)該在modelsim和Quartusii中編譯通過的基礎(chǔ)。
Tcl語(yǔ)句文件:
本次設(shè)計(jì)中使用的是命令界面,使用Tcl語(yǔ)言進(jìn)行操作,所以需要準(zhǔn)備好相應(yīng)的Tcl命令以便對(duì)設(shè)計(jì)進(jìn)行約束,本設(shè)計(jì)將它存放在constraints目錄下。
庫(kù)文件:
本設(shè)計(jì)采用的是tsmc公司的0.18um標(biāo)準(zhǔn)單元庫(kù)的所有文件,存放在目錄:/usr/eda/designKit/和/usr/synopsys/dc2016/下面,在.synopsys_dc.setup文件中配置時(shí)將這些文件的路徑配置進(jìn)去,啟動(dòng)軟件的時(shí)候軟件會(huì)加載.synopsys_dc.setup即可調(diào)用這些標(biāo)準(zhǔn)庫(kù)文件。
3.2.1 綜合環(huán)境
本次設(shè)計(jì)是運(yùn)行在deepin Linux操作系統(tǒng)環(huán)境下的。Linux是一套免費(fèi)使用和自由傳播的類Unix操作系統(tǒng),是一個(gè)基于POSIX和UNIX的多用戶、多任務(wù)、支持多線程和多CPU的操作系統(tǒng)。它能運(yùn)行主要的UNIX工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。它支持32位和64位硬件。Linux繼承了Unix以網(wǎng)絡(luò)為核心的設(shè)計(jì)思想,是一個(gè)性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。
本次課程設(shè)計(jì)所使用的綜合工具Design Compiler(簡(jiǎn)稱DC),是synopsys 公司的ASIC 綜合器產(chǎn)品,它可以完成將硬件。描述語(yǔ)言所做的RTL級(jí)描述自動(dòng)轉(zhuǎn)換成優(yōu)化的門級(jí)網(wǎng)表。DC 是工業(yè)界標(biāo)準(zhǔn)的邏輯綜合工具,也是Synopsys 最核心的產(chǎn)品。它根據(jù)設(shè)計(jì)描述和約束條件并針對(duì)特定的工藝庫(kù)將輸入的VHDL或者Verilog 的RTL 描述自動(dòng)綜合出一個(gè)優(yōu)化的門級(jí)電路。
3.2.1 綜合過程
設(shè)計(jì)的主要完整步驟為:啟動(dòng)DC軟件同時(shí)加載啟動(dòng)項(xiàng)文件→讀入源代碼→鏈接→設(shè)計(jì)檢查→時(shí)序路徑約束→綜合環(huán)境約束→編譯綜合→輸出報(bào)告→結(jié)束。 流程圖大致如下圖3.1所示:
以上為綜合總體過程,接下來將要詳細(xì)地進(jìn)行邏輯綜合操作,首先打開Linux中命令終端。進(jìn)入以準(zhǔn)備好的.synopsys_dc.setup文件所在路徑。執(zhí)行命令,打開Design Compiler。進(jìn)入Tcl命令界面,命令如下:
cd /home/dcLab/work
lmgrd -c /usr/synopsys/license/synopsys.dat
design_version&
之后可以打開Design compiler軟件,其啟動(dòng)終端如圖所示:
Design compiler軟件有GUI界面,既可以在Linux終端中進(jìn)行Tcl語(yǔ)句約束和操作,也可在GUI圖形界面操作,其界面如圖所示:
打開軟件的時(shí)候軟件會(huì)調(diào)用已經(jīng)配置好的.synopsys_dc.setup 文件,定位到標(biāo)準(zhǔn)文件庫(kù)中和搜索路徑。 接下來就可以導(dǎo)入已經(jīng)準(zhǔn)備好的文件,被存放在之前在家目錄下自己建立的 code目錄下,其完整路徑為/home/victor/dclab /rtl/code中的文件。導(dǎo)入時(shí)DC會(huì)初步檢查代碼的問題,沒有問題才能導(dǎo)入成功。下一步就是要與庫(kù)文件進(jìn)行鏈接,如下圖3.4所示:
鏈接成功則.synopsys_dc.setup 文件配置正確,下一步進(jìn)行時(shí)序約束和環(huán)境約束,在constraints目錄下存放著書寫好的Tcl約束命令,可以一步導(dǎo)入約束命令快速完成約束,也可以在GUI界面一步步進(jìn)行約束的必要操作,本設(shè)計(jì)在終端進(jìn)行一步輸入操作,之后進(jìn)行編譯和分析報(bào)告并作出修改,如圖所示:
四 報(bào)告分析
完成上一節(jié)的約束操作后,完成編譯就可以查看輸出各種關(guān)于設(shè)計(jì)的報(bào)告分析,通過報(bào)告分析可以得出設(shè)計(jì)中的各種缺陷和問題,以及約束是否有錯(cuò)誤、違反約束原則,然后進(jìn)行優(yōu)化和修改達(dá)到滿意的結(jié)果。
4.1約束報(bào)告
約束報(bào)告將給出之前關(guān)于本設(shè)計(jì)的約束是否違反了約束規(guī)則或者導(dǎo)致設(shè)計(jì)的性能變差,以及有沒有對(duì)時(shí)序要求完成合適的約束。本設(shè)計(jì)約束沒有違反約束規(guī)則,具體報(bào)告如下所示:
**************************************** Report : constraint-all_violators-max_area-max_delay-max_leakage_power-max_dynamic_power-max_total_power-cell_degradation-max_toggle_rate-max_capacitance-max_fanout-max_transition-multiport_net Design : encode_decode_top Version: L-2016.03-SP1 Date : Fri Jun 21 13:50:36 2019 **************************************** This design has no violated constraints.4.2時(shí)序報(bào)告
電路有不同的信號(hào)時(shí)序路徑(Timing Path),每條路徑都有一個(gè)起點(diǎn)和一個(gè)
終點(diǎn)。起點(diǎn)是電路的輸入端口或電路中寄存器的時(shí)鐘管腳,終點(diǎn)是電路的輸出端
口或時(shí)序器件(sequential devices)中除時(shí)鐘管腳外的其它輸入管腳。生成的時(shí)序報(bào)告由4 個(gè)部分組成:路徑信息部分(Path Information Section),路徑延
時(shí)部分(Path Delay Section),路徑要求部分(Path Required Section),總結(jié)部分(Summary Section),本設(shè)計(jì)時(shí)序報(bào)告如下所示:
4.3 面積報(bào)告
面積報(bào)告中列出了設(shè)計(jì)的端口、單元、線網(wǎng)和引用的數(shù)目。設(shè)計(jì)的面積被分為組合、非組合以及互連線。分別顯示出組合邏輯面積,時(shí)序邏輯面積,估計(jì)的互聯(lián)線面積,單元器件總面積。本設(shè)計(jì)的面積報(bào)告如下:
**************************************** Report : area Design : encode_decode_top Version: L-2016.03-SP1 Date : Fri Jun 21 13:51:54 2019 **************************************** Library(s) Used:slow (File: /usr/eda/designKit/UMCArtisan18/aci/sc-x/synopsys/slow.db) Number of ports: 323 Number of nets: 1106 Number of cells: 781 Number of combinational cells: 692 Number of sequential cells: 76 Number of macros/black boxes: 0 Number of buf/inv: 144 Number of references: 1 Combinational area: 12530.549085 Buf/Inv area: 1892.721663 Noncombinational area: 5125.982357 Macro/Black Box area: 0.000000 Net Interconnect area: 202814.354431 Total cell area: 17656.531442 Total area: 220470.885873 ***** End Of Report *****設(shè)計(jì)總結(jié)
通過這次數(shù)字集成電路的課程設(shè)計(jì),我鞏固了自己的 FPGA 的相關(guān)知識(shí),更加深入的掌握了 verilog HDL 語(yǔ)言的用法 。開始設(shè)計(jì)的過程中,遇到了很多困難,原理搞不懂,軟件使用不熟練,verilog HDL 語(yǔ)法問題,其中對(duì)于相關(guān)資料的檢索也是一個(gè)我們都比較弱的方面。
經(jīng)過詢問老師后,以及老師給的指導(dǎo)和理論課程的跟進(jìn),外加上課講解的許多典型電路的例子,自己也在bing和google中搜索到了一些題目相關(guān)的資料,最后在eetop(易特創(chuàng)新網(wǎng))中找到了一個(gè)比較好的例子,通過對(duì)它的探索,經(jīng)過不斷的仿真與調(diào)試,逐漸實(shí)現(xiàn)了課題要求的功能,隨后逐步完善代碼,完成了設(shè)計(jì)任務(wù)。
本次的課程設(shè)計(jì)是繼續(xù)上學(xué)期的EDA技術(shù)與FPGA應(yīng)用的課程設(shè)計(jì)做的。重點(diǎn)在于運(yùn)用Liunx環(huán)境下的design compiler軟件進(jìn)行邏輯綜合,對(duì)電路各部分進(jìn)行約束,對(duì)于一個(gè)設(shè)計(jì)從提出到實(shí)際生產(chǎn)使用的一步步流程越來越深刻。 而其中的難點(diǎn)在于我們對(duì)于Linux系統(tǒng)環(huán)境的接觸比較少,導(dǎo)致這個(gè)軟件的安裝破解以及環(huán)境變量的配置比較困難,其中遇到了許多問題,而解決這些問題花費(fèi)了大量的時(shí)間和精力,不過經(jīng)過這個(gè)過程后,我對(duì)于Linux的知識(shí)也是更加的深入了,我相信這將會(huì)對(duì)以后Linux系統(tǒng)下的軟件使用會(huì)有所幫助。
8b/10b 編解碼在高速串行網(wǎng)絡(luò)數(shù)據(jù)數(shù)據(jù)傳輸中充當(dāng)不可或缺的角色,通過本次的課程設(shè)計(jì),我明確它的傳輸轉(zhuǎn)換原理,對(duì)于以后 FPGA 的學(xué)習(xí),更能加深理解。
參考文獻(xiàn)
[1] Lattice Semiconductor 8b/10b Encoder/Decoder
[2] A DC-Balanced, Partitioned-Block, 8B/10B Transmission Code
[3] 8b/10b Encoder v5.0 XILINX
[4] 8B/10B 編碼器的設(shè)計(jì)及實(shí)現(xiàn) 李宥謀
[5] 8B_10B 編碼詳解 _靈思邁_新浪博客
附錄I:程序源代碼
//控制模塊 module core_control(original_clk,rstn,led_sel,led_drv,key1,key2,key3); /* 用于連接各個(gè)模塊,控制輸入輸出, 顯示 */ input original_clk,rstn; output [7:0] led_drv; output [5:0] led_sel; input key1,key2,key3; //指定 端口的類型 wire original_clk,rstn; wire [7:0] led_drv; wire [5:0] led_sel; wire key1,key2,key3; wire [8:0] original_in; wire [9:0] out; wire [9:0] out_standard; wire [43:0] data; wire rd; wire correct; wire check; wire decode_in; wire [7:0] decode_out; assign check = (out_standard==out) ? 1 : 0 ; //空的 內(nèi)容 因?yàn)槠鹗嫉牡谝粋€(gè)4bit 燈的不能用的(滅了)作為游動(dòng) 標(biāo)志 assign data[43:40] = {4'b0}; //將輸入內(nèi)容送顯示模塊 assign data[39:28] = {3'b0,original_in}; // 將輸出結(jié)果送顯示模塊 assign data[27:16] = {2'h0,out}; //將rd送顯示模塊 assign data[15:12] = {3'b000,rd}; //將檢查標(biāo)志位送顯示模塊 assign data[11:8] = {3'b000,correct}; //將解碼的結(jié)果送顯示模塊 assign data[7:0] = {decode_out}; //標(biāo)準(zhǔn)真值表校驗(yàn) //original_in,out_standard,rd_standard,key1,rstn encode_standard biaozhun(.original_in(original_in),.out_standard(out_standard),.rd(rd),.key1(key1),.rstn(rstn)); //編碼主模塊例化 encode8b10b1 en8to10(.original_in(original_in),.original_clk(original_clk),.rstn(rstn),.key1(key1),.rd(rd),.out(out));//解碼計(jì)算模塊例化 decode_calculation de10to8( .decode_in(out), .decode_out(decode_out), .correct(correct) );//顯示模塊 display2 segxianshi(.original_clk(original_clk),.led_sel(led_sel),.led_drv(led_drv),.rstn(rstn),.data(data));//輸入模塊 encode_input_generate shuru(.original_clk(original_clk),.key1(key1),.key2(key2),.key3(key3),.original_in(original_in),.rstn(rstn)); Endmodule//編碼主模塊 module encode8b10b1(original_in,original_clk,rstn,key1,rd,out);//定義輸入輸出端口 input original_clk,rstn; input [8:0] original_in; output rd; output [9:0] out; input key1; //指定 端口的類型 wire [8:0] original_in; wire original_clk,rstn; wire [7:0] led_drv; wire [5:0] led_sel; wire key1,key2,key3; // 定義中間變量 reg rd_temp; reg [7:0] in; wire [4:0] in_5b_to_6b; wire [2:0] in_3b_to_4b; wire [6:0] out_5b_to_6b; wire [4:0] out_3b_to_4b; wire [9:0] out_common; wire [9:0] out_particular; wire [9:0] out; wire [11:0] in12b; wire rd; reg k; wire rd_common; wire rd_particular; always@(posedge key1 or negedge rstn)begin if(!rstn)in <= 0; elsein <= original_in[7:0]; endalways@(posedge key1 or negedge rstn)begin if(!rstn)k <= 0; elsek <= original_in[8]; endalways@(posedge key1 or negedge rstn)begin if(!rstn)rd_temp <= 0; elserd_temp <= rd; endassign in12b = {out_3b_to_4b[4:0],out_5b_to_6b[6:0]}; assign in_5b_to_6b = in[4:0]; assign in_3b_to_4b = in[7:5]; assign out = k ? out_particular : out_common; assign rd = k ? rd_particular:rd_common;//5b6b默認(rèn)編碼模塊 default_encode_5b_to_6b en56(.in_5b_to_6b(in_5b_to_6b),.out_5b_to_6b(out_5b_to_6b));//3b4b默認(rèn)編碼模塊 default_encode_3b_to_4b en34 (.in_3b_to_4b(in_3b_to_4b),.out_3b_to_4b(out_3b_to_4b),.out_5b_to_6b(out_5b_to_6b));//差異度計(jì)算模塊 running_disparity running_disparity(.rd_temp(rd_temp),.in12b(in12b),.out_common(out_common),.rd_common(rd_common)); //特殊編碼模塊 particular particular(.in_particular(in),.out_particular(out_particular),.rd_temp(rd_temp),.rd_particular(rd_particular)); Endmodule//3b到4b默認(rèn)編碼模塊 module default_encode_3b_to_4b(out_5b_to_6b,in_3b_to_4b,out_3b_to_4b); /* 2. 3b到4b默認(rèn)編碼 有三種情況1:一的數(shù)量和零的數(shù)量相等,此時(shí)標(biāo)志位為0 2:一的數(shù)量是3個(gè),零的數(shù)量是1個(gè) ,此時(shí)標(biāo)志位為1其中 3b為111時(shí),其編碼取決于 6b 的結(jié)果*/ input [2:0] in_3b_to_4b; input [6:0] out_5b_to_6b; output [4:0] out_3b_to_4b; wire [6:0] out_5b_to_6b; wire [2:0] in_3b_to_4b; reg [4:0] out_3b_to_4b; always @ (in_3b_to_4b)begincase (in_3b_to_4b)3'b000: out_3b_to_4b <= 5'b11011;3'b001: out_3b_to_4b <= 5'b01001;3'b010: out_3b_to_4b <= 5'b00101;3'b011: out_3b_to_4b <= 5'b01100;3'b100: out_3b_to_4b <= 5'b11101;3'b101: out_3b_to_4b <= 5'b01010;3'b110: out_3b_to_4b <= 5'b00110;3'b111: begin if(!out_5b_to_6b[6] && (out_5b_to_6b[0]==out_5b_to_6b[1]))out_3b_to_4b <= 5'b10111;elseout_3b_to_4b <= 5'b11110; endendcase end endmodule //5b到6b默認(rèn)編碼模塊 module default_encode_5b_to_6b(in_5b_to_6b,out_5b_to_6b); /* 1. 5b到6b默認(rèn)編碼 有兩種情況 1:一的數(shù)量和零的數(shù)量相等,此時(shí)標(biāo)志位為0 2:一的數(shù)量是4個(gè),0的數(shù)量是2個(gè),此時(shí)標(biāo)志位為1*/ input [4:0] in_5b_to_6b; output [6:0] out_5b_to_6b; wire [4:0] in_5b_to_6b; reg [6:0] out_5b_to_6b; always @ (in_5b_to_6b)begincase(in_5b_to_6b) //out_5b_to_6b 的 最高位用于標(biāo)志 1的數(shù)量和0 的數(shù)量是否一樣, 一樣 為0,否則,為1,即代表有4個(gè)15'h00: out_5b_to_6b <= 7'b1100111;5'h01: out_5b_to_6b <= 7'b1011101;//…5'h1f: out_5b_to_6b <= 7'b1101011;Endcase end endmodule //差異度計(jì)算和10bit校驗(yàn)?zāi)K module running_disparity(rd_temp,rd_common,in12b,out_common); input rd_temp; input [11:0] in12b; output [9:0] out_common; output rd_common; wire rd_temp; wire [11:0] in12b; reg [9:0] out_common; reg rd_common; always@(in12b or rd_temp)begin case({in12b[11],in12b[6],rd_temp})3'b000: begin out_common <= { in12b[5:0] , in12b[10:7] } ; rd_common <= rd_temp ; end3'b001: beginout_common <= (in12b[5:0]==111000)?{~in12b[5:0],in12b[10:7]}:{in12b[5:0],in12b[10:7]} ; rd_common <= rd_temp ; end3'b010: begin out_common <= { in12b[5:0] , in12b[10:7] } ; rd_common <= ~rd_temp ; end3'b011: begin out_common <= { ~in12b[5:0] , in12b[10:7] } ; rd_common <= ~rd_temp ; end3'b100: begin out_common <= { in12b[5:0] , in12b[10:7] } ; rd_common <= ~rd_temp ; end3'b101: begin out_common <= (in12b[5:0]==111000)?{~in12b[5:0],~in12b[10:7]}:{ in12b[5:0],~in12b[10:7]} ; rd_common <= ~rd_temp ; end3'b110: begin out_common <= { in12b[5:0] , ~in12b[10:7] } ; rd_common <= ~rd_temp ; end3'b111: begin out_common <= { ~in12b[5:0] , in12b[10:7] } ; rd_common <= ~rd_temp ; end Endcase end endmodule? //顯示模塊 moduledisplay2(original_clk,led_sel,led_drv,rstn,key1,key2,key3,data); //定義輸入輸出 input [43:0] data; input original_clk,rstn; input key1,key2,key3; output [7:0] led_drv; output [5:0] led_sel; // 定義輸入輸出接口類型 wire [43:0] data; //需要顯示的動(dòng)態(tài)數(shù)據(jù),其中有4bit 作為 標(biāo)志位 不能使用,所以可以用的位數(shù)有36bit 可以顯示 9個(gè)4bit數(shù)據(jù) wire original_clk,rstn; //原始的時(shí)鐘輸入,時(shí)鐘頻率50M HZ,復(fù)位接按鍵 wire key1,key2,key3; //三個(gè)按鍵控制信號(hào),可以控制進(jìn)行輸入數(shù)據(jù) reg [7:0] led_drv; //最終的seg譯碼信號(hào),控制數(shù)碼管顯示內(nèi)容 wire [5:0] led_sel; //最終的顯示輸出,對(duì)外端口 //定義各種中間變量的類型 reg [23:0] contain; //contain 是 6個(gè)數(shù)碼管的當(dāng)前顯示內(nèi)容, 一個(gè)數(shù)碼管顯示4bit 所以 contain 一共24bit reg [7:0] cnt; wire clk; //顯示需要的經(jīng)過適度分頻的時(shí)鐘信號(hào),clk為分頻模塊是輸出時(shí)鐘信號(hào) reg [3:0] led_drv_temp; //顯示碼的中間變量,表示當(dāng)前一個(gè)周期 顯示的 4bit 數(shù)據(jù)內(nèi)容 reg [5:0] led_sel_temp; //顯示輸出的中間變量,因?yàn)樾枰右粋€(gè)控制信號(hào),所以要先有一個(gè)中間值 暫存過程 reg [5:0] switch; // 顯示數(shù)碼管開關(guān)信號(hào) 控制 做為動(dòng)態(tài)顯示的一個(gè)滅的標(biāo)志,否則 無法判斷這個(gè)一組數(shù)據(jù)的起始位 reg [28:0] cnt1s; //計(jì)數(shù)信號(hào),通過計(jì)數(shù),實(shí)現(xiàn)分頻,進(jìn)而控制數(shù)碼管 在分時(shí)復(fù)用的基礎(chǔ)上,加上游動(dòng)顯示 //接近1秒鐘的分頻,50M時(shí)鐘 ,分 2的25次冪 頻 時(shí)間 可以作為移位的驅(qū)動(dòng)信號(hào) always@(posedge original_clk or negedge rstn)begin if(!rstn) cnt1s =0; else if( cnt1s[28:25]==4'b1011 )//直接對(duì)其高bit位進(jìn)行譯碼,運(yùn)算 省去了 中間的計(jì)數(shù)信號(hào),即將計(jì)數(shù)值直接作為 分好頻 并且記好數(shù)的信號(hào)cnt1s[28:25] = 4'b0000;else cnt1s=cnt1s+1'b1; end // 25進(jìn)制計(jì)數(shù)器,的最高位,作為移動(dòng)信號(hào)// 對(duì)移動(dòng)信號(hào)計(jì)數(shù),5進(jìn)制計(jì)數(shù)// 計(jì)數(shù)值譯碼 always@(cnt1s)begincase(cnt1s[28:25])//不同的計(jì)數(shù)值,對(duì)應(yīng)不同的數(shù)據(jù)內(nèi)容,進(jìn)行動(dòng)態(tài)游動(dòng) 移位4'b0000: contain <= data[43:20] ;4'b0001: contain <= data[39:16] ;4'b0010: contain <= data[35:12] ;4'b0011: contain <= data[31:8] ;4'b0100: contain <= data[27:4] ;4'b0101: contain <= data[23:0] ;4'b0110: contain <= { data[19:0] , data[43:40] } ;4'b0111: contain <= { data[15:0] , data[43:36] } ;4'b1000: contain <= { data[11:0] , data[43:32] } ;4'b1001: contain <= { data[7:0] , data[43:28] } ;4'b1010: contain <= { data[3:0] , data[43:24] } ;default: contain <= 23'h0 ; endcase end // data是要顯示的全部比特?cái)?shù)據(jù) // contain是當(dāng)前顯示的比特?cái)?shù)據(jù) // 起始位 數(shù)碼管滅 標(biāo)記 開關(guān)控制 always@(cnt1s)begincase(cnt1s[28:25])//對(duì)cnt1s進(jìn)行相應(yīng)譯碼,選擇控制 滅的數(shù)碼管的位置4'b0000: switch <= 6'b100000;4'b0001: switch <= 6'b000000;4'b0010: switch <= 6'b000000;4'b0011: switch <= 6'b000000;4'b0100: switch <= 6'b000000;4'b0101: switch <= 6'b000000;4'b0110: switch <= 6'b000001;4'b0111: switch <= 6'b000010;4'b1000: switch <= 6'b000100;4'b1001: switch <= 6'b001000;4'b1010: switch <= 6'b010000;default: switch <= 6'b000000;endcase end //選通開關(guān) 加入 assign led_sel = switch|led_sel_temp; //持續(xù)賦值,讓led_sel 最終的信號(hào) 是在switch的控制下進(jìn)行 的 // 選擇信號(hào)移位操作 always@(posedge clk or negedge rstn )beginif(!rstn)led_sel_temp <= 6'b000000;elseif(led_sel_temp==6'b000000)// led_sel <= (switch[5:0])|(6'b111110);led_sel_temp <= 6'b111110;else// led_sel = led_selled_sel_temp = {led_sel_temp[4:0],led_sel_temp[5]}; end // 選擇信號(hào) 對(duì)應(yīng)數(shù)據(jù)傳遞 always@(led_sel_temp or rstn)begin// begincase(led_sel_temp)6'b111110:led_drv_temp <= contain[3:0];6'b111101:led_drv_temp <= contain[7:4];6'b111011:led_drv_temp <= contain[11:8];6'b110111:led_drv_temp <= contain[15:12];6'b101111:led_drv_temp <= contain[19:16];6'b011111:led_drv_temp <= contain[23:20];default:led_drv_temp <= 4'b0000;endcase end // 顯示內(nèi)容 seg 數(shù)碼管譯碼 always@(led_drv_temp or rstn or cnt1s)begin if(!rstn)led_drv <= 8'b10111111; //H_else begincase(led_drv_temp)// 一個(gè)數(shù)碼管顯示的4bit數(shù)據(jù)顯示seg譯碼4'b0000: led_drv <= 8'b11000000;4'b0001: led_drv <= 8'b11111001;4'b0010: led_drv <= 8'b10100100;4'b0011: led_drv <= 8'b10110000;4'b0100: led_drv <= 8'b10011001;4'b0101: led_drv <= 8'b10010010;4'b0110: led_drv <= 8'b10000010;4'b0111: led_drv <= 8'b11111000;4'b1000: led_drv <= 8'b10000000;4'b1001: led_drv <= 8'b10010000;4'b1010: led_drv <= 8'b10001000;4'b1011: led_drv <= 8'b10000011;4'b1100: led_drv <= 8'b11000110;4'b1101: led_drv <= 8'b10100001;4'b1110: led_drv <= 8'b10000110;4'b1111: led_drv <= 8'b10001110;// default: led_drv <= 8'b10000001; //H_endcaseend end control_baud fenpin(.SAMPLING(clk),.CLK(original_clk),.RSTN(rstn)); //連接 分頻模塊 對(duì)原始時(shí)鐘進(jìn)行分頻 Endmodule //輸入模塊 // `timescale 1ns/1ns module encode_input_generate(key1,key2,key3,original_in,original_clk,rstn); //本模塊是產(chǎn)生 編碼模塊需要的輸入數(shù)據(jù)的 input key1,key2,key3; input rstn,original_clk; output [8:0] original_in; wire key1,key2,key3; wire rstn,original_clk; wire [8:0] original_in; //隨機(jī)模式 reg cnt0; reg [7:0] cnt1; assign original_in[8:0] = {cnt0,cnt1[7:0]}; always@(posedge original_clk or negedge rstn)beginif(!rstn)cnt1 <= 0;else beginif(!key2) cnt1 <= cnt1+1'b1;end end //key3用于 標(biāo)記 特殊值 always@(posedge key3 or negedge rstn)begin if(!rstn)cnt0 <= 0;else begincnt0 <= !cnt0;end end //按鍵輸入模式 reg [3:0] cnt1; reg [3:0] cnt0; // cnt0為低四位輸入,cnt1為高四位輸入 assign original_in = {cnt1,cnt0}; // key3控制低4位輸入 always@(posedge key3 or negedge rstn)beginif(!rstn)cnt0 <= 0;elsecnt0 = cnt0+1'b1; end always@(posedge key2 or negedge rstn)beginif(!rstn)cnt1 <= 0;elsecnt1 = cnt1+1'b1; end //計(jì)數(shù)輸入模式reg [7:0] cnt8b; reg i,j; assign original_in = {1'b0,cnt8b}; always@(posedge key2 or negedge rstn)beginif(!rstn)i <= 0;else i = 1; end always@(posedge key3 or negedge rstn)beginif(!rstn)j <= 0;else j = 1; end always@(i or j)beginif(!rstn)cnt8b <= 0;else begin if(i) cnt8b <= cnt8b + 1'b1;else if(j) cnt8b <= cnt8b - 1'b1;else;end end Endmodule//消抖模塊 module xiaodou(CLK,KEY_IN,RSTN,KEY); input CLK,KEY_IN,RSTN; output KEY; wire CLK,KEY_IN; reg KEY; reg[11:0] cnt4000; //可能有按鍵按下,開始計(jì)數(shù) always@(posedge CLK or negedge RSTN) if(!RSTN) cnt4000<=0; else begin if(!KEY_IN) if(cnt4000==4000) cnt4000<=0; else cnt4000<=cnt4000+1'b1; //理論 20ms 消抖時(shí)間 else cnt4000<=0; //抖動(dòng)時(shí),計(jì)數(shù)會(huì)被清零 end //產(chǎn)生消抖后的信號(hào) always@(posedge CLK or negedge RSTN) if(!RSTN) KEY<=1; else begin if(!KEY_IN) begin if(cnt4000==4000) KEY<=0; end else KEY<=1; end endmodule附錄II:設(shè)計(jì)約束腳本
#讀入設(shè)計(jì)代碼 read_verilog { encode_decode_top.v control_baud.v core_control.v decode_calculation.v running_disparity.v default_encode_3b_to_4b.v default_encode_5b_to_6b.v encode8b10b1.v encode_input_generate.v particular.v display2.v } #約束設(shè)計(jì)指定 current_design encode_decode_top.v #鏈接和檢查 Link check_design #時(shí)間、電阻、電容、電壓、電流單位 set_units -time ns -resistance kOhm -capacitancepF-voltageV-current mA #工作環(huán)境 set_operating_conditions -max slow -max_library slow.db:slow\-min fast -min_library fast.db:fast #線載模型指定 set_wire_load_model -name tsmc18_wl20 -library slow.db:slow #設(shè)定輸出網(wǎng)表的格式規(guī)則,以消除門級(jí)網(wǎng)表中的tri和assign set verilogout_no_tri true set_fix_multiple_port_nets -all -buffer_constants #設(shè)定本地庫(kù) set_local_link_library { /usr/eda/designKit/cic_tsmc18/synDC/slow.db, /usr/eda/designKit/cic_tsmc18/synDC/fast.db, /usr/eda/designKit/cic_tsmc18/synDC/tpz973gbc.db, /usr/eda/designKit/cic_tsmc18/synDC/tpz973gwc.db, /usr/eda/designKit/cic_tsmc18/synDC/tpz973gtc.db } #檢查時(shí)序 check_timing #設(shè)定時(shí)鐘 create_clock [get_ports original_clk] -period 20 -waveform {10 20} set_clock_uncertainty -setup 0.3 [get_clocks original_clk] set_clock_latency -source -max 0.3 [get_clocks original_clk] set_clock_latency -max 0.1 [get_clocks original_clk] set_clock_transition -max 0.2 [get_clocks original_clk] #避免在綜合優(yōu)化時(shí)對(duì)時(shí)鐘或復(fù)位線上插入buffer set_ideal_network [get_ports original_clk] set_ideal_network [get_ports rstn] set_dont_touch_network [get_clocks original_clk] set_dont_touch_network [get_ports rstn] #輸入延時(shí) set_input_delay -clock original_clk -max 7 [get_ports key1] set_input_delay -clock original_clk -max 7 [get_ports key2] set_input_delay -clock original_clk -max 7 [get_ports key3] #輸出延時(shí) set_output_delay -clock original_clk -max 7 [get_ports {led_sel[5]}] set_output_delay -clock original_clk -max 7 [get_ports {led_sel[4]}] set_output_delay -clock original_clk -max 7 [get_ports {led_sel[3]}] set_output_delay -clock original_clk -max 7 [get_ports {led_sel[2]}] set_output_delay -clock original_clk -max 7 [get_ports {led_sel[1]}] set_output_delay -clock original_clk -max 7 [get_ports {led_sel[0]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[7]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[6]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[5]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[4]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[3]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[2]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[1]}] set_output_delay -clock original_clk -max 7 [get_ports {led_drv[0]}] #設(shè)定最大扇出 set_max_fanout 20 [current_design] #設(shè)定最大渡越時(shí)間 set_max_transition 2 [current_design] #指定單元庫(kù)模型 set_driving_cell -lib_cell PDIDGZ -library tpz973gwc [get_ports key1] set_driving_cell -lib_cell PDIDGZ -library tpz973gwc [get_ports key2] set_driving_cell -lib_cell PDIDGZ -library tpz973gwc [get_ports key3] #輸出負(fù)載電容 set_load -pin_load 3 [get_ports {led_sel[5]}] set_load -pin_load 3 [get_ports {led_sel[4]}] set_load -pin_load 3 [get_ports {led_sel[3]}] set_load -pin_load 3 [get_ports {led_sel[2]}] set_load -pin_load 3 [get_ports {led_sel[1]}] set_load -pin_load 3 [get_ports {led_sel[0]}] set_load -pin_load 3 [get_ports {led_drv[7]}] set_load -pin_load 3 [get_ports {led_drv[6]}] set_load -pin_load 3 [get_ports {led_drv[5]}] set_load -pin_load 3 [get_ports {led_drv[4]}] set_load -pin_load 3 [get_ports {led_drv[3]}] set_load -pin_load 3 [get_ports {led_drv[2]}] set_load -pin_load 3 [get_ports {led_drv[1]}] set_load -pin_load 3 [get_ports {led_drv[0]}] #編譯模式 compile -map high #輸出時(shí)序報(bào)告 rc > log/rc.log #輸出網(wǎng)表 write -f verilog -hier -o encode_decode.v #輸出綜合數(shù)據(jù)文件 write -f ddc -hier -o encode_decode.ddc #輸出延時(shí)文件 write_sdf encode_decode.sdf 1附錄III:.synopsys_dc.setup文件
set company "SYLU" set designer "student" set libPath "/usr/eda/designKit/UMCArtisan18/aci" set search_path " /home/victor/dclab/rtl/code /home/victor/dclab/constraints $libPath/sc-x/synopsys $libPath/io/synopsys /usr/eda/libraries/syn /usr/synopsys/dc2016/dw/sim_ver /usr/synopsys/dc2016/dw/syn_ver " set link_library " /usr/eda/designKit/cic_tsmc18/synDC/slow.db /usr/eda/designKit/cic_tsmc18/synDC/fast.db /usr/eda/designKit/cic_tsmc18/synDC/tpz973gbc.db /usr/eda/designKit/cic_tsmc18/synDC/tpz973gwc.db /usr/eda/designKit/synopsys/libraries/syn/dw_foundation.sldb" set target_library " /usr/eda/designKit/UMCArtisan18/aci/sc-x/synopsys/slow.db /usr/eda/designKit/UMCArtisan18/aci/sc-x/synopsys/fast.db /usr/eda/designKit/UMCArtisan18/aci/io/synopsys/umc18io3v5v_slow.db /usr/eda/designKit/UMCArtisan18/aci/io/synopsys/umc18io3v5v_fast.db" set edifout_netlist_only "TRUE" set verilogout_no_tri true set bus_inference_style {%s[%d]} set bus_naming_style {%s[%d]} set hdlout_internal_busses true #change_names -hierarchy -rule verilog define_name_rules name_rule -allowed {a-z A-Z 0-9 _} -max_length 255 -type cell define_name_rules name_rule -allowed {a-z A-Z 0-9 _[]} -max_length 255 -type net define_name_rules name_rule -map {{"\\*cell\\*" "cell"}} alias rc "report_timing"總結(jié)
以上是生活随笔為你收集整理的基于FPGA 的8b10b编解码电路前端电路设计的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 传智播客杨中科老师的全13季 C#、As
- 下一篇: 想做数字孪生项目?这款数据可视化软件值得