基于FPGA 的8b10b編解碼電路前端電路設計
摘 要
本設計是采用EDA技術設計的一種8B /10B 編解碼電路,實現了在高速的串行數據傳輸中的直流平衡。該編解碼電路設計大體上可以由五個模塊構成,分別是默認編碼模塊、差異度計算模塊、編碼校正模塊、并串轉換模塊、顯示模塊。
采用Verilog HDL 描述語言進行電路的設計、使用modelsim 10.2a 進行功能仿真、在通過Quartus II 13.1 進行FPGA邏輯綜合和適配下載,并在Alter 公司的Cyclone IV E 的芯片EP4CE6F17C8 上實現并完成測試,最后用tcl語言編寫約束腳本和啟動文件,通過Synopsys的“Design Compiler”進行邏輯綜合。
關鍵詞: FPGA;Verilog HDL;8B10B編解碼;tcl;邏輯綜合。
前 言
可編程的“萬能芯片” FPGA(Field-Programmable Gate Array)——現場可編程門陣列,是指一切通過軟件手段更改、配置器件內部連接結構和邏輯單元,完成既定設計功能的數字集成電路。
FPGA可以實現怎樣的能力,主要取決于它所提供的門電路的規模。如果門電路的規模足夠大,FPGA通過編程可以實現任意芯片的邏輯功能,例如ASIC、DSP甚至PC處理器等。這就是FPGA為什么被稱之為“萬能芯片”的原因。
以硬件描述語言(Verilog或VHDL)所完成的電路設計,可以經過簡單的綜合與布局,快速的燒錄至 FPGA 上進行測試,是現代 IC設計驗證的技術主流。這些可編輯元件可以被用來實現一些基本的邏輯門電路。在大多數的FPGA里面,這些可編輯的元件里也包含記憶元件例如觸發器(Flip-flop)或者其他更加完整的記憶塊。
FPGA的核心具有可編程靈活性高、開發周期短、并行計算可編程靈活性高等優點。系統設計師可以根據需要通過可編輯的連接把FPGA內部的邏輯塊連接起來,就好像一個電路試驗板被放在了一個芯片里。一個出廠后的成品FPGA的邏輯塊和連接可以按照設計者而改變,所以FPGA可以完成所需要的邏輯功能。
1總體電路結構設計
1.1 基本原理
在高速的串行數據傳輸中 ,傳送的數據被編碼 成自同步的數據流 ,就是將數據和時鐘組合成單一 的信號進行傳送 ,使得接收方能容易準確地將數據 和時鐘分離 ,而且要達到令人滿意的誤碼率 ,其關鍵 技術在于串行傳輸中數據的編碼方法。目前大多數高速串行標準都采用 8B /10B 編碼方案 ,例如光纖 通道 1、PCI - Exp ress、串行 ATA、以太網、XAU I、In2 finiBand和串行相連 SCSI等。使用 8B /10B編碼技 術 ,較好地解決了以下問題。
(1)轉換密度 :保證數據流中有足夠的信號轉 換。采用 8B /10B編碼方法 ,數據流中連續的“1”或 連續的“0”不超過 5個 ,使接收端鎖相環 (PLL)能正 常工作 ,避免接收端時鐘漂移或同步丟失而引起數 據丟失。
(2) DC補償 : 在高速的數據傳輸線路中 ,一般 采用差分信號 ,需要直流分量盡量小 ,而 8B /10B有 DC補償功能 ,即鏈路中不會隨著時間推移而出現 DC偏移。
(3)檢錯 : 8B /10B編碼采用冗余方式 ,將 8位 的數據和一些特殊字符按照特定的規則編碼成 10 位的數據 ,根據這些規則 ,能檢測出傳輸過程中發生 錯誤的信息。
(4)特殊字符 : 8B /10B編碼規定了一些特殊字符 ,可用作幀同步字符和其他的分隔符或控制字符。
8B/10B,也叫做8字節/10字節或8B10B。8B/10B方式最初由IBM公司于1983年發明并應用于ESCON(200M互連系統),由Al Widmer和Peter Franaszek在IBM的刊物“研究與開發”上描述。把 8位數據字節轉換成串行傳輸使用的 10位碼。8B /10B編碼 保證了 1和 0的相對平衡組合 ,而與數據值無關 ,簡 化了時鐘恢復 ,降低了接收機成本。編碼提供的其它位還促進了誤碼檢測。8B /10B編碼提供了構建串行通信使用的一套基礎數據和控制字符。許多獨立標準都以這個公共字符集為基礎 ,定義更高的協議層。
1.2 電路總體圖
1.3 電路功能框圖
1.4 電路接口表
1.5 驗證方案
為了驗證編解碼數據的正確性,首先在modelsim中仿真,通過觀察信號的時序波形來對照真值表驗證,在邏輯層面仿真成功后,再通過quartus II將各個模塊燒錄開發板,通過顯示模塊,將數據通過數碼管顯示出來進而進行驗證數據的正確性,其中編碼的數據來源于開發板上面的按鍵輸入,解碼的數據來源于編碼數據的結果。
經過開發板的下載驗證,通過結果分析可知,本方案符合課設設計任務書的要求,具有一定的可行性。
2模塊設計
本設計按功能大體上可以分為8個子模塊,分別為默認編碼模塊、差異度運算模塊、編碼校驗模塊、解碼模塊、并串轉換模塊、消抖模塊、輸入模塊和顯示模塊。
2.1 默認編碼模塊設計
8b/10b編碼是將一組連續的8位數據分解成兩組數據,一組3位,一組5位,經過編碼后分別成為一組4位的代碼和一組6位的代碼,從而組成一組10位的數據發送出去。相反,解碼是將1組10位的輸入數據經過變換得到8位數據位。
數據值可以統一的表示為DX.Y或KX.Y,其中D表示為數據代碼,K表示為特殊的命令代碼,X表示輸入的原始數據的低5位EDCBA,Y 表示輸入的原始數據的高3位HGF。
3B/4B 和 5B/6B 是通過映射機制進行編碼的,這種映射機制已經標準化成相應的映射表
根據表格我們可以看出:5b/6b 編碼的值可能有一種,還可能有兩種。如果是前者,那么6b中的“1”的數量和“0” 的數量一定是相等的,如果是后者,那么編碼6b的第兩種情況為按位取反的結果。
所以,在進行編碼過程中,先對5b/6b 進行默認編碼,如果是第一種情況(即1的數量和0的數量相同),就在6b的最高位添加一個標記位,并且用0進行標記,否則(1的數量比0的數量多),就用1最為標記。3b/4b 默認編碼過程與之相似,需要注意的是當3b=111時,有兩組編碼結果,為了避免10b的結果中0或1的數量連續超過4個的情況,4b碼1000 和0111 這組編碼出現的特殊情況外,其它的編碼規則同上面分析的3B 碼具有雙值編碼的情況,此時的編碼取0001 和1110 這組編碼。
2.2 差異度運算設計
8B/10B 編碼中有兩個重要的概念,不均等性( disparity )和極性偏差( runningdisparity , RD)。前者表示‘ 1’和‘ 0’個數的差值,其有如下規律:
(1)若 ABCDE 的 Disparity 值為 - 1, 那么在‘ RD- ’項中生成的 abcde 與 ABCDE 有一一對應的關系 , 并且 i=‘1’ , 此時除 ABCDE= ‘00011’外 abcde i 是唯一的 ;
(2)若 ABCDE 的 Disparity 值為 + 1, 那么在‘ RD-’項中生成的 abcde 與 ABCDE 有一一對應的關系 , 并且 i=‘0’, 此時除 ABCDE = ‘ 11100’外 abcdei 是唯一的 ;
(3)若 ABCDE 的 Disparity 值為 + 3, 那么在‘ RD-’項中生成的 abcde 與 ABCDE 有一一對應的關系 , 并且 i=‘0’, 此時 abcdei 是互為反碼的兩個值 ;
(4)若 ABCDE 的 Disparity 為其他值 , 此時 abcde i 具有互為反碼的兩個值 , 對這些特殊的‘RD –’項中的值可直接用查表法實現。
后者的取值分為以下三種:
(1)當碼字中‘ 1’比‘ 0’多 , 或者 4B 碼為 1100,或者 6B 碼為 111000 時, 該碼字被定義為正極性碼 ,這個時候 RD 取正 ;
(2)當碼字中‘ 1’比‘ 0’少 , 或者 4B 碼為 0011,或者 6B 碼為 000111 時, 該碼字被定義為負極性碼 , 這個時候 RD 取負 ;
(3)其他碼字定義為中性碼 , RD 取其前一碼字的 RD 游程值。
2.3 編碼校驗模塊設計
在3b4b默認編碼模塊中,編碼產生的數據大致有兩種情況,“0”和“1”的數量相等,或者“0”和“1”的數量不等,這兩種情況和上一次數據的RD值組合產生幾種結果:
為了方便判斷各個狀態的邏輯情況,將4b數據中1的個數多的情況標記為1,否則為0,6b數據同理。
2.4 解碼模塊設計
為得到快的解碼處理速度 , 電路設計中采用數據解碼并行處理完成, 而由數據 選擇器控制選擇輸出數據的拓撲結構來實現 。8B /10B編碼電路的原理是對 8B 數據編碼時 將數據分為高 3位和低 5位兩部分 , 分別進行 3B / 4B編碼和 5B /6B編碼結合在一起而生成最終的 10B數據 。 8B /10B數據解碼電路 , 分為 3B /4B 解 碼電路和 5B /6B解碼電路兩個部分, 共同實現解碼 的完整數據解碼。
由于解碼不需要考慮差異度RD的值,從10bit 到 8bit ,所以解碼的數據具有一一對應關系,可以通過4b到3b、6b到5b 直接查表來實現。可以參照附錄I。
其中,需要注意的是,10bit是解碼原始數據一共有2^10 1024種情況,但是與其對應的8bit的編碼只有2^8 256種結果,這樣如果解碼的原始數據 10bit 不在編碼產生的范圍內,則需要解出一個錯誤標志信息,產生8bit 的數據為設定的默認值。
2.5 消抖模塊設計
消抖模塊主要的核心是對可能產生的按鍵信號進行判斷是否是外部按鍵輸 入而不是內部電平波動。一旦電平波動則開始計數,因為使用按鍵消抖時間為 20ms,實際消抖時間 20—40ms。 消抖只考慮的按鍵按下的抖動,忽略按鍵上彈的電平抖動,因為這段抖動不影響電路的功能和性能,如圖為消抖模塊內部接口波形圖:
一旦檢測到 KEY_IN 按鍵電平發生波動,為 0 開始計數,為 1 清除計數值,
當電平穩定為0時才能完成一次穩定計數到4000,產生消抖后的按鍵信號KEY。 而維持按鍵長時間不抬起,KEY 也一直為 0 不變。當按鍵 KEY_IN 抬起時,盡管 按鍵任然會產生電平波動,但是 KEY 信號穩定拉高為 1,這樣完成一次消抖 同步到本地時鐘的過程。下面列出消抖模塊的端口信號表:
2.6 并串轉換模塊
由于傳輸中所用的是串行的數據流,所以,編碼完成后需要將編號的并行10bit結果轉換成串行的10bit,才能進行數據傳輸。
同理,在解碼過程之前,也需要將串行的10bit轉換成并行的以便于解碼。
并行轉換的數據為10bit,通過一個十進制的計數器進行控制,當計數值為0的時候,mask打開,并行數據送入移位寄存器中,并把最低位的一比特數據送出串行輸出口。當計數值為非零時,mask選通前一個D觸發器的輸出,一個時鐘上升沿,將數據向右移動移位,將數據送到串行輸出端。
2.7 輸入模塊設計
本模塊需要提供給FPGA的功能模塊需要編碼的8bit原始數據,這樣整個系統才能運行,開發板上面可以利用的資源為四個物理按鍵,其中系統復位rstn占用一個,所以可以供用戶自定義的按鍵有三個,本模塊需要通過3個按鍵輸入需要驗證的8bit 并行數據。
本模塊一共設計了三種工作模式,分別為計數輸入模式、按鍵輸入模式和隨機模式。計數輸入模式:通過按鍵控制輸入的8bit數據逐次加一,這樣可以編碼出順序的相鄰數據。按鍵輸入模式:通過兩個按鍵控制,key1控制8bit的高4位,key2控制8bit的低4位,對key3的下降沿進行計數,即可指定輸入數據的值。隨機模式:通過一個key2按鍵進行輸入,當檢測到key2位低電平的時候,對計數變量cnt進行循環加一操作,計數變量cnt為8bit,最后將cnt的值通過持續賦值給輸入,這樣每當key2松開的時候,可以認為輸入的數據為一個隨機的值。
2.8 顯示模塊設計
本次使用的FPGA開發板上面的數碼管為6個8段數碼管,并且通過sel信號進行選通,drv信號輸入顯示編碼數據。由于所有是數碼管并聯在一起,若想在不同的數碼管上面顯示不同的數據,需要分時復用數碼管,首先對開發板上面的50M時鐘進行分頻,用分好頻率的時鐘進行移位和選通操作。
數值0—F分別譯碼成用于數碼管顯示的8bit顯示碼,分共陽和共陰的區別譯碼不同,需要根據不同的 FPGA 開發板來確定。八段數碼管分別為 A,B,C,D,E,F,G,DP八段,前七段用于顯示數字以及字母等字符,DP段在數碼管上右下角,點亮后為小數點。對于多個數碼管同一時刻只能點亮一個數碼管。如圖2.8所示:
由于本設計使用的FPGA開發板的數碼管顯示是采用的是共陽極數碼管,且是六個并聯的獨立數碼管,有6個數碼管選通引腳,在這個設計中只需要四個數碼管即可,現在列出共陽八段極數碼管的顯示碼:
除了以上16個對應的顯示碼外,額外還有一個特殊的現實,僅僅用于電路復位是數碼管上的現實,數碼管僅g段點亮,其顯示碼為10111111。
需要顯示的數據有編碼輸入的數據、編碼產生的輸出數據、解碼的數據,所以6個數碼管顯示資源有些不足,這里采用了數碼管動態游動顯示的方式實現,定義一個選通信號,通過控制這個信號使數據中第一個4bit的位置的數碼管熄滅,這樣數據游走的同時,可以明顯看出數據串的第一位,這樣一來,就實現了數碼管的高效率復用。
三 設計約束與邏輯綜合
3.1設計約束
這里需要使用design compiler工具,可以參考design compiler使用教程
3.1.1約束策略
對于一個由時鐘控制的數字邏輯電路來說,時序是最為重要的。encode_decode_top.v是本設計所要約束的文件。本設計定的時鐘CLK的頻率為50MHZ,即周期為20ns。輸入為key[3:0],輸出為led_sel[5:0]和led_drv[7:0],他們都是由CLK信號同步控制,所以這些信號延時約占時鐘信號的35%,即輸入輸出延時設置為7ns。本次對此電路的綜合約束需要分為以下幾部分:對CLK時鐘信號進行設置,對每個輸入輸出信號的約束,對扇出和驅動負載能力能度需要進行約束設置,最后輸出報告。
以上約束只有對本電路結構非常熟悉才能對自己的時序約束更完善。
3.1.2 約束腳本
首先是讀入源代碼,也就是HDL文本描述的設計文件,此處不用制定目錄,Design Compiler會在搜索目錄中搜索。tcl語句如下:
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 }
讀入設計原文件后,一般設定當前設計,這樣約束條件才可能有針對性的施加。tcl語句如下:
current_design encode_decode_top.v
設定當前設計后,要完成鏈接,也就是將設計與庫鏈接起來,用于映射過程中搜索相應的單元,完成綜合。tcl語句如下:
Link
檢查設計,主要完成檢查轉換的設計。tcl語句如下:
check_design
然后對設計設定時序約束,這是最重要的一項約束,用于設定設計的工作速度。針對不同的設計部分,有不同的約束方法。針對本次設計,采用全同步,雙時鐘工作的實際情況。以下語句設定時鐘及屬性、輸入輸出信號時間余量。
設定名稱為original_clk的時鐘,由于采用50MHz的時鐘,故設定時鐘周期為20ns。
tcl語句如下:
create_clock [get_ports original_clk] -period 20 -waveform {10 20}
設定為理想時鐘不對時鐘網絡進行驅動從而在使得綜合工具在優化階段
不去修改或移除該object,對時鐘設置dont_touch屬性,那么就可以避免在綜合優化時對時鐘上插入 buffer。tcl語句如下:
set_dont_touch_network [get_clocks " original_clk"]
set_ideal_network [get_ports " original_clk "]
告訴綜合器不要對復位進行驅動。tcl語句如下:
set_dont_touch_network [get_ports rstn]
set_ideal_network [get_ports rstn]
設定輸入信號最大時間延時。tcl語句如下:
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]
設定輸出信號最大時間延時。tcl語句如下:
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]}]
檢查時序。tcl語句如下:
check_timing
設定綜合的操作條件。tcl語句如下:
set_operating_conditions -max slow -max_library slow.db:slow\ -min fast -min_library fast.db:fast
設定線負載模型,本設計選擇tsmc18_wl20模型。tcl語句如下:
set_wire_load_model -name tsmc18_wl20 -library slow.db:slow
設定輸出負載電容。tcl語句如下:
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]}]
設定扇出最大負載能力。tcl語句如下:
set_max_fanout 20 [current_design]
驅動能力設定。tcl語句如下:
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]
設定輸出網表的格式規則,以消除gate level nelist中的assign。tcl語句如下:
set verilogout_no_tri true
set_fix_multiple_port_nets -all -buffer_constants
最大能力進行綜合。tcl語句如下:
compile -map high
輸出時序報告。tcl語句如下:
rc > log/rc.log
輸出網表。tcl語句如下:
write -f verilog -hier -o encode_decode.v
輸出綜合數據文件。tcl語句如下:
write -f ddc -hier -o encode_decode.ddc
輸出延時文件。tcl語句如下:
write_sdf encode_decode.sdf
輸出scl命令文件,在file>Save Info輸出encode_decode.dc,文件中將會完整的包含所有tcl約束命令和各種環境、線載配置等。
除了以上報告外,還應該輸出編譯后對整個設計的各個方面的報告文件,如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等報告文件。
3.2邏輯綜合
3.2.1 綜合文件
首先在家目錄(home)下建立 home/victor/dclab 作為本次實驗 dc 的操作主目錄。在 dclab 目錄下,建立設計存放目錄如 rtl/code、約束文件目錄如 constraints、輸出網表文件目錄ntlist、報告輸出目錄report、文件目錄work
等等,在綜合前需要準備以下幾類文件:
.synopsys_dc.setup文件即啟動項文件:
在這個文件中,需要將所用到的庫單元文件的路徑和電路設計文件所存放的路徑寫入,以便軟件在工作時能夠找到這些文件并正確識別,本設計將它存放在
work目錄下。主要配置libPath、Search_Path、Link_library、Target_library、
Symbol_library,本設計.synopsys_dc.setup文件具體配置見附錄B。
*.v文件:
本設計為 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
本設計所使用電路描述語言為verilog HDL語言,所以需要將功能電路的設計文件準備好以便用于約束綜合,這些文件應該在modelsim和Quartusii中編譯通過的基礎。
Tcl語句文件:
本次設計中使用的是命令界面,使用Tcl語言進行操作,所以需要準備好相應的Tcl命令以便對設計進行約束,本設計將它存放在constraints目錄下。
庫文件:
本設計采用的是tsmc公司的0.18um標準單元庫的所有文件,存放在目錄:/usr/eda/designKit/和/usr/synopsys/dc2016/下面,在.synopsys_dc.setup文件中配置時將這些文件的路徑配置進去,啟動軟件的時候軟件會加載.synopsys_dc.setup即可調用這些標準庫文件。
3.2.1 綜合環境
本次設計是運行在deepin Linux操作系統環境下的。Linux是一套免費使用和自由傳播的類Unix操作系統,是一個基于POSIX和UNIX的多用戶、多任務、支持多線程和多CPU的操作系統。它能運行主要的UNIX工具軟件、應用程序和網絡協議。它支持32位和64位硬件。Linux繼承了Unix以網絡為核心的設計思想,是一個性能穩定的多用戶網絡操作系統。
本次課程設計所使用的綜合工具Design Compiler(簡稱DC),是synopsys 公司的ASIC 綜合器產品,它可以完成將硬件。描述語言所做的RTL級描述自動轉換成優化的門級網表。DC 是工業界標準的邏輯綜合工具,也是Synopsys 最核心的產品。它根據設計描述和約束條件并針對特定的工藝庫將輸入的VHDL或者Verilog 的RTL 描述自動綜合出一個優化的門級電路。
3.2.1 綜合過程
設計的主要完整步驟為:啟動DC軟件同時加載啟動項文件→讀入源代碼→鏈接→設計檢查→時序路徑約束→綜合環境約束→編譯綜合→輸出報告→結束。 流程圖大致如下圖3.1所示:
以上為綜合總體過程,接下來將要詳細地進行邏輯綜合操作,首先打開Linux中命令終端。進入以準備好的.synopsys_dc.setup文件所在路徑。執行命令,打開Design Compiler。進入Tcl命令界面,命令如下:
cd /home/dcLab/work
lmgrd -c /usr/synopsys/license/synopsys.dat
design_version&
之后可以打開Design compiler軟件,其啟動終端如圖所示:
Design compiler軟件有GUI界面,既可以在Linux終端中進行Tcl語句約束和操作,也可在GUI圖形界面操作,其界面如圖所示:
打開軟件的時候軟件會調用已經配置好的.synopsys_dc.setup 文件,定位到標準文件庫中和搜索路徑。 接下來就可以導入已經準備好的文件,被存放在之前在家目錄下自己建立的 code目錄下,其完整路徑為/home/victor/dclab /rtl/code中的文件。導入時DC會初步檢查代碼的問題,沒有問題才能導入成功。下一步就是要與庫文件進行鏈接,如下圖3.4所示:
鏈接成功則.synopsys_dc.setup 文件配置正確,下一步進行時序約束和環境約束,在constraints目錄下存放著書寫好的Tcl約束命令,可以一步導入約束命令快速完成約束,也可以在GUI界面一步步進行約束的必要操作,本設計在終端進行一步輸入操作,之后進行編譯和分析報告并作出修改,如圖所示:
四 報告分析
完成上一節的約束操作后,完成編譯就可以查看輸出各種關于設計的報告分析,通過報告分析可以得出設計中的各種缺陷和問題,以及約束是否有錯誤、違反約束原則,然后進行優化和修改達到滿意的結果。
4.1約束報告
約束報告將給出之前關于本設計的約束是否違反了約束規則或者導致設計的性能變差,以及有沒有對時序要求完成合適的約束。本設計約束沒有違反約束規則,具體報告如下所示:
****************************************
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時序報告
電路有不同的信號時序路徑(Timing Path),每條路徑都有一個起點和一個
終點。起點是電路的輸入端口或電路中寄存器的時鐘管腳,終點是電路的輸出端
口或時序器件(sequential devices)中除時鐘管腳外的其它輸入管腳。生成的時序報告由4 個部分組成:路徑信息部分(Path Information Section),路徑延
時部分(Path Delay Section),路徑要求部分(Path Required Section),總結部分(Summary Section),本設計時序報告如下所示:
****************************************
Report : timing-path full-delay max-max_paths 1-sort_by group
Design : encode_decode_top
Version: L-2016.03-SP1
Date : Sun Jul 7 16:27:37 2019Operating Conditions: slow Library: slow
Wire Load Model Mode: topStartpoint: kongzhi/segxianshi/cnt1s_reg[0](rising edge-triggered flip-flop clocked by original_clk)Endpoint: kongzhi/segxianshi/cnt1s_reg[28](rising edge-triggered flip-flop clocked by original_clk)Path Group: original_clkPath Type: maxDes/Clust/Port Wire Load Model Libraryencode_decode_top tsmc18_wl20 slowPoint Incr Pathclock original_clk (rise edge) 10.00 10.00clock network delay (ideal) 0.00 10.00kongzhi/segxianshi/cnt1s_reg[0]/CK (DFFRHQX1) 0.00 10.00 rkongzhi/segxianshi/cnt1s_reg[0]/Q (DFFRHQX1) 1.08 11.08 rkongzhi/segxianshi/add_47/A[0](display2_DW01_inc_0) 0.00 11.08 r kongzhi/segxianshi/add_47/U1_1_1/CO (ADDHXL) 0.45 11.54 rkongzhi/segxianshi/add_47/U1_1_2/CO (ADDHXL) 0.43 11.97 rkongzhi/segxianshi/add_47/U1_1_3/CO (ADDHXL) 0.43 12.41 rkongzhi/segxianshi/add_47/U1_1_4/CO (ADDHXL) 0.43 12.84 rkongzhi/segxianshi/add_47/U1_1_5/CO (ADDHXL) 0.43 13.28 rkongzhi/segxianshi/add_47/U1_1_6/CO (ADDHXL) 0.43 13.71 rkongzhi/segxianshi/add_47/U1_1_7/CO (ADDHXL) 0.43 14.14 rkongzhi/segxianshi/add_47/U1_1_8/CO (ADDHXL) 0.43 14.58 rkongzhi/segxianshi/add_47/U1_1_9/CO (ADDHXL) 0.43 15.01 rkongzhi/segxianshi/add_47/U1_1_10/CO (ADDHXL) 0.43 15.45 rkongzhi/segxianshi/add_47/U1_1_11/CO (ADDHXL) 0.43 15.88 rkongzhi/segxianshi/add_47/U1_1_12/CO (ADDHXL) 0.43 16.31 rkongzhi/segxianshi/add_47/U1_1_13/CO (ADDHXL) 0.43 16.75 rkongzhi/segxianshi/add_47/U1_1_14/CO (ADDHXL) 0.43 17.18 rkongzhi/segxianshi/add_47/U1_1_15/CO (ADDHXL) 0.43 17.62 rkongzhi/segxianshi/add_47/U1_1_16/CO (ADDHXL) 0.43 18.05 rkongzhi/segxianshi/add_47/U1_1_17/CO (ADDHXL) 0.43 18.49 rkongzhi/segxianshi/add_47/U1_1_18/CO (ADDHXL) 0.43 18.92 rkongzhi/segxianshi/add_47/U1_1_19/CO (ADDHXL) 0.43 19.35 rkongzhi/segxianshi/add_47/U1_1_20/CO (ADDHXL) 0.43 19.79 rkongzhi/segxianshi/add_47/U1_1_21/CO (ADDHXL) 0.43 20.22 rkongzhi/segxianshi/add_47/U1_1_22/CO (ADDHXL) 0.43 20.66 rkongzhi/segxianshi/add_47/U1_1_23/CO (ADDHXL) 0.43 21.09 rkongzhi/segxianshi/add_47/U1_1_24/CO (ADDHXL) 0.43 21.52 rkongzhi/segxianshi/add_47/U1_1_25/CO (ADDHXL) 0.43 21.96 rkongzhi/segxianshi/add_47/U1_1_26/CO (ADDHXL) 0.43 22.39 rkongzhi/segxianshi/add_47/U1_1_27/CO (ADDHXL) 0.43 22.82 rkongzhi/segxianshi/add_47/U2/Y (XOR2X1) 0.40 23.22 fkongzhi/segxianshi/add_47/SUM[28] (display2_DW01_inc_0) 0.00 23.22 fkongzhi/segxianshi/U113/Y (AND2X1) 0.35 23.57 fkongzhi/segxianshi/cnt1s_reg[28]/D (DFFRHQX1) 0.00 23.57 fdata arrival time 23.57clock original_clk (rise edge) 30.00 30.00clock network delay (ideal) 0.00 30.00kongzhi/segxianshi/cnt1s_reg[28]/CK (DFFRHQX1) 0.00 30.00 rlibrary setup time -0.43 29.57data required time 29.57-------------------------------------------------------------------------data required time 29.57data arrival time -23.57-------------------------------------------------------------------------slack (MET) 5.99
***** End Of Report *****
4.3 面積報告
面積報告中列出了設計的端口、單元、線網和引用的數目。設計的面積被分為組合、非組合以及互連線。分別顯示出組合邏輯面積,時序邏輯面積,估計的互聯線面積,單元器件總面積。本設計的面積報告如下:
****************************************
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 *****
設計總結
通過這次數字集成電路的課程設計,我鞏固了自己的 FPGA 的相關知識,更加深入的掌握了 verilog HDL 語言的用法 。開始設計的過程中,遇到了很多困難,原理搞不懂,軟件使用不熟練,verilog HDL 語法問題,其中對于相關資料的檢索也是一個我們都比較弱的方面。
經過詢問老師后,以及老師給的指導和理論課程的跟進,外加上課講解的許多典型電路的例子,自己也在bing和google中搜索到了一些題目相關的資料,最后在eetop(易特創新網)中找到了一個比較好的例子,通過對它的探索,經過不斷的仿真與調試,逐漸實現了課題要求的功能,隨后逐步完善代碼,完成了設計任務。
本次的課程設計是繼續上學期的EDA技術與FPGA應用的課程設計做的。重點在于運用Liunx環境下的design compiler軟件進行邏輯綜合,對電路各部分進行約束,對于一個設計從提出到實際生產使用的一步步流程越來越深刻。 而其中的難點在于我們對于Linux系統環境的接觸比較少,導致這個軟件的安裝破解以及環境變量的配置比較困難,其中遇到了許多問題,而解決這些問題花費了大量的時間和精力,不過經過這個過程后,我對于Linux的知識也是更加的深入了,我相信這將會對以后Linux系統下的軟件使用會有所幫助。
8b/10b 編解碼在高速串行網絡數據數據傳輸中充當不可或缺的角色,通過本次的課程設計,我明確它的傳輸轉換原理,對于以后 FPGA 的學習,更能加深理解。
參考文獻
[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 編碼器的設計及實現 李宥謀
[5] 8B_10B 編碼詳解 _靈思邁_新浪博客
附錄I:程序源代碼
//控制模塊
module core_control(original_clk,rstn,led_sel,led_drv,key1,key2,key3);
/*
用于連接各個模塊,控制輸入輸出, 顯示
*/
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 ;
//空的 內容 因為起始的第一個4bit 燈的不能用的(滅了)作為游動 標志
assign data[43:40] = {4'b0};
//將輸入內容送顯示模塊
assign data[39:28] = {3'b0,original_in};
// 將輸出結果送顯示模塊
assign data[27:16] = {2'h0,out};
//將rd送顯示模塊
assign data[15:12] = {3'b000,rd};
//將檢查標志位送顯示模塊
assign data[11:8] = {3'b000,correct};
//將解碼的結果送顯示模塊
assign data[7:0] = {decode_out};
//標準真值表校驗
//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));//解碼計算模塊例化
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默認編碼模塊
default_encode_5b_to_6b en56(.in_5b_to_6b(in_5b_to_6b),.out_5b_to_6b(out_5b_to_6b));//3b4b默認編碼模塊
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));//差異度計算模塊
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默認編碼模塊
module default_encode_3b_to_4b(out_5b_to_6b,in_3b_to_4b,out_3b_to_4b);
/*
2. 3b到4b默認編碼 有三種情況1:一的數量和零的數量相等,此時標志位為0 2:一的數量是3個,零的數量是1個 ,此時標志位為1其中 3b為111時,其編碼取決于 6b 的結果*/
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默認編碼模塊
module default_encode_5b_to_6b(in_5b_to_6b,out_5b_to_6b);
/*
1. 5b到6b默認編碼 有兩種情況 1:一的數量和零的數量相等,此時標志位為0 2:一的數量是4個,0的數量是2個,此時標志位為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 的 最高位用于標志 1的數量和0 的數量是否一樣, 一樣 為0,否則,為1,即代表有4個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
//差異度計算和10bit校驗模塊
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;
//需要顯示的動態數據,其中有4bit 作為 標志位 不能使用,所以可以用的位數有36bit 可以顯示 9個4bit數據
wire original_clk,rstn;
//原始的時鐘輸入,時鐘頻率50M HZ,復位接按鍵
wire key1,key2,key3;
//三個按鍵控制信號,可以控制進行輸入數據
reg [7:0] led_drv;
//最終的seg譯碼信號,控制數碼管顯示內容
wire [5:0] led_sel;
//最終的顯示輸出,對外端口
//定義各種中間變量的類型
reg [23:0] contain;
//contain 是 6個數碼管的當前顯示內容, 一個數碼管顯示4bit 所以 contain 一共24bit
reg [7:0] cnt;
wire clk;
//顯示需要的經過適度分頻的時鐘信號,clk為分頻模塊是輸出時鐘信號
reg [3:0] led_drv_temp;
//顯示碼的中間變量,表示當前一個周期 顯示的 4bit 數據內容
reg [5:0] led_sel_temp;
//顯示輸出的中間變量,因為需要加一個控制信號,所以要先有一個中間值 暫存過程
reg [5:0] switch;
// 顯示數碼管開關信號 控制 做為動態顯示的一個滅的標志,否則 無法判斷這個一組數據的起始位
reg [28:0] cnt1s;
//計數信號,通過計數,實現分頻,進而控制數碼管 在分時復用的基礎上,加上游動顯示
//接近1秒鐘的分頻,50M時鐘 ,分 2的25次冪 頻 時間 可以作為移位的驅動信號
always@(posedge original_clk or negedge rstn)begin
if(!rstn) cnt1s =0;
else if( cnt1s[28:25]==4'b1011 )//直接對其高bit位進行譯碼,運算 省去了 中間的計數信號,即將計數值直接作為 分好頻 并且記好數的信號cnt1s[28:25] = 4'b0000;else cnt1s=cnt1s+1'b1;
end
// 25進制計數器,的最高位,作為移動信號// 對移動信號計數,5進制計數// 計數值譯碼
always@(cnt1s)begincase(cnt1s[28:25])//不同的計數值,對應不同的數據內容,進行動態游動 移位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是要顯示的全部比特數據
// contain是當前顯示的比特數據
// 起始位 數碼管滅 標記 開關控制
always@(cnt1s)begincase(cnt1s[28:25])//對cnt1s進行相應譯碼,選擇控制 滅的數碼管的位置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
//選通開關 加入
assign led_sel = switch|led_sel_temp;
//持續賦值,讓led_sel 最終的信號 是在switch的控制下進行 的
// 選擇信號移位操作
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
// 選擇信號 對應數據傳遞
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
// 顯示內容 seg 數碼管譯碼
always@(led_drv_temp or rstn or cnt1s)begin
if(!rstn)led_drv <= 8'b10111111; //H_else begincase(led_drv_temp)// 一個數碼管顯示的4bit數據顯示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));
//連接 分頻模塊 對原始時鐘進行分頻
Endmodule
//輸入模塊
// `timescale 1ns/1ns
module encode_input_generate(key1,key2,key3,original_in,original_clk,rstn);
//本模塊是產生 編碼模塊需要的輸入數據的
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;
//隨機模式
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用于 標記 特殊值
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
//計數輸入模式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; //可能有按鍵按下,開始計數
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 消抖時間
else cnt4000<=0; //抖動時,計數會被清零
end //產生消抖后的信號
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:設計約束腳本
#讀入設計代碼
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
}
#約束設計指定
current_design encode_decode_top.v
#鏈接和檢查
Link check_design
#時間、電阻、電容、電壓、電流單位
set_units -time ns -resistance kOhm -capacitancepF-voltageV-current mA
#工作環境
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
#設定輸出網表的格式規則,以消除門級網表中的tri和assign
set verilogout_no_tri true
set_fix_multiple_port_nets -all -buffer_constants
#設定本地庫
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
}
#檢查時序
check_timing
#設定時鐘
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]
#避免在綜合優化時對時鐘或復位線上插入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]
#輸入延時
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]
#輸出延時
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]}]
#設定最大扇出
set_max_fanout 20 [current_design]
#設定最大渡越時間
set_max_transition 2 [current_design]
#指定單元庫模型
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]
#輸出負載電容
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
#輸出時序報告
rc > log/rc.log
#輸出網表
write -f verilog -hier -o encode_decode.v
#輸出綜合數據文件
write -f ddc -hier -o encode_decode.ddc
#輸出延時文件
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"