日韩欧美自拍在线观看-欧美精品在线看片一区二区-高清性视频一区二区播放-欧美日韩女优制服另类-国产精品久久久久久av蜜臀-成人在线黄色av网站-肥臀熟妇一区二区三区-亚洲视频在线播放老色-在线成人激情自拍视频

基于Verilog語(yǔ)言的可維護(hù)性設(shè)計(jì)技術(shù)

出處:Eric King 發(fā)布于:2008-08-12 11:42:21

隨著集成電路制造技術(shù)的發(fā)展,對(duì)設(shè)計(jì)提出了更多的挑戰(zhàn),隨著設(shè)計(jì)復(fù)雜度的增加,又提出了片上系統(tǒng)(SoC)的概念。為了加速設(shè)計(jì)收斂,設(shè)計(jì)重用、可測(cè)性設(shè)計(jì)、可驗(yàn)證性設(shè)計(jì)和可維護(hù)性設(shè)計(jì)得到了更多重視。本文以VerilogHDL為例,對(duì)可維護(hù)性設(shè)計(jì)進(jìn)行了初步探討。

1、設(shè)計(jì)重用與可維護(hù)性設(shè)計(jì)

  設(shè)計(jì)重用是一個(gè)很大的概念,嚴(yán)格來(lái)講,可驗(yàn)證性設(shè)計(jì)和可維護(hù)性設(shè)計(jì)都在設(shè)計(jì)重用之列??删S護(hù)性設(shè)計(jì)的目的本身就是便于設(shè)計(jì)重用,便于讓后來(lái)人讀懂前人所寫的代碼,但設(shè)計(jì)重用包括的內(nèi)容更廣泛。

  設(shè)計(jì)重用講的是設(shè)計(jì)總體風(fēng)格而不是設(shè)計(jì)的細(xì)節(jié),“it is about forests, rather than trees”。重要的概念:本地化(locality)――一定要盡量使問題本地化,這樣有利于問題的排除。對(duì)于大的設(shè)計(jì)尤為重要。

三條基本原則

  盡量采用全同步設(shè)計(jì),將輸入和輸出寄存,這樣有利于將時(shí)序優(yōu)化本地化

  采用bottom-up驗(yàn)證方法,保證每個(gè)子模塊的功能是正確的,然后再進(jìn)行整體驗(yàn)證。

   花時(shí)間設(shè)計(jì)一個(gè)好的設(shè)計(jì)規(guī)范,力圖使這樣的規(guī)范具有好的體系結(jié)構(gòu)和模塊劃分,這樣有利于本地化的有效實(shí)現(xiàn)。

  一個(gè)好的設(shè)計(jì)應(yīng)該包括:完備的文檔、好風(fēng)格的代碼、詳盡的注釋、良好易用的驗(yàn)證環(huán)境和魯棒的腳本。

  影響設(shè)計(jì)重用的障礙本質(zhì)上說(shuō)是管理和企業(yè)文化;開發(fā)和管理內(nèi)部IP資源是的重用挑戰(zhàn)。

  關(guān)于設(shè)計(jì)重用這里不再討論,否則就有喧賓奪主之嫌了。

2、關(guān)于代碼可擴(kuò)展性的一點(diǎn)討論

  代碼可擴(kuò)展性實(shí)際上也包括在設(shè)計(jì)重用之內(nèi)。代碼可擴(kuò)展性或稱可擴(kuò)展性設(shè)計(jì)要求便于向?qū)?lái)新的設(shè)計(jì)過(guò)渡。比如64位的PCI標(biāo)準(zhǔn)出來(lái)的時(shí)候,現(xiàn)行的32位PCI接口設(shè)計(jì)模塊可以通過(guò)比較簡(jiǎn)單的改動(dòng)而變?yōu)?4位,而不需要一切從頭再來(lái)。一般設(shè)計(jì)中通過(guò)定義參數(shù)和宏來(lái)便于修改。典型例子就是總線

`define WORD 16
`define DWORD 32
reg [`WORD-1:0] intruction
reg [`DWORD-1:0] data_bus,addr_bus;
當(dāng)然代碼可擴(kuò)展性不僅僅包括參數(shù)和宏的使用,如下例:
module tri_buf(in,out, ena);
parameter WIDTH=8;
input [WIDTH-1:0] in;
output[WIDTH-1:0] out;
input ena;
assign out= ena?in:’bz;
endmodule

  這是一段有潛在問題的代碼,Verilog將高位擴(kuò)展為0來(lái)匹配輸出,所以當(dāng)WIDTH>32時(shí),上述代碼是有問題的,仿真的時(shí)候甚至都看不出來(lái),因此不利于可擴(kuò)展性。象這樣的問題可以用Verilog lint等工具來(lái)檢查。

3、可讀性重要

  可讀性重要。許多設(shè)計(jì)者有個(gè)習(xí)慣:追求盡量用短的代碼來(lái)完成同樣的功能,國(guó)內(nèi)許多考試中也要求用少于多少行的代碼完成某某功能(很不好的傾向)。對(duì)于HDL,我不推薦這樣的風(fēng)格,因?yàn)榫C合工具會(huì)幫助你完成優(yōu)化工作。我的建議是:同樣的代碼可長(zhǎng)可短,不要為了減少行數(shù)而影響可讀性。如下例:

Module rrarb(request,grant,reset,clk);
Input [1:0] request;
Output[1:0]grant;
Input reset;
Input clk;
Wire winner;
Reg last_winner;
Reg [1:0] grant;
Wire[1:0] next_grant;

Assign next_grant[0]=~reset&(request[0] & (~request[1]|last_winner));
Assugn next_grant[1]=~reset& (request[1] &(~request[0]| ~last_winner));
Assign winner=~reset & ~next_grant[0] &(last_winner | next_grant[1]);
Always @(posedge clk)
Begin
Last_winner=winner;
Grant=next_grant;
End
當(dāng)request[1:0]=2’b00,時(shí),last_winner會(huì)發(fā)生什么變化?上面的代碼可讀性較之下面的代碼差很多。
Module rrarb(request,grant,reset,clk);
Input [1:0] request;
Output[1:0]grant;
Input reset;
Input clk;
Wire winner;
Reg last_winner;
Reg [1:0] grant;
Always @(posedge clk)
Begin
If(reset) begin
Grant<=2’b00;
Last_winner<=0;
End
Else begin
   Grant<=2’b00;
If(request!=2’b00) begin:find_winner
Reg winner;
Case(request)
2’b01:winner<=0;
2’b10:winner<=1;
2’b11:if (last_winner==1’b0) winner<=1;
       else                 winner<=0;
default:winner<=0;
endcase
grant[winner] <=1’b1;
last_winner<=winner;
end
end
end
endmodule

  上述兩個(gè)代碼的綜合結(jié)果差不多。而且上面段代碼在always塊內(nèi)采用阻塞賦值的方法也存在潛在問題。

4、要有好的注釋風(fēng)格

  要有好的注釋風(fēng)格。減少注釋的行數(shù)跟節(jié)約代碼的行數(shù)一樣,我不推薦。像代碼有好壞一樣,注釋也有好壞之分。比如:

//increment addr
addr<=addr+1;

  上例中的注釋就是一句廢話,因?yàn)榈刂芳?是不言自明的。這樣的注釋反而會(huì)影響可讀性。好的注釋應(yīng)該給出該段代碼的使用目的,它能夠給不熟悉這段代碼的人以信息。如下例:

//In burst mode,the bytes are written in consecutive addresses.Need to access the next address to verify that the next byte was properly saved.
Addr<=addr+1;

  關(guān)于如何注釋我在設(shè)計(jì)重用里面講過(guò),這里不再重復(fù),請(qǐng)參考[2]。

5、應(yīng)盡量將聲明本地化

  這種辦法有點(diǎn)類似于C++中封裝的概念,應(yīng)盡量保持變量的可見性在必要的范圍內(nèi),不要產(chǎn)生不必要的交互。
如下例:
integer I;

always
begin
for(I=0;I<32;I=I+1) begin … end
end

always
begin
    for(I=15;I>=0;I=I-1)   begin … end
end

  對(duì)于兩段代碼來(lái)講,I是全局的,他們的不必要的交互會(huì)產(chǎn)生不可預(yù)料的結(jié)果。在verilog里面,你可以將I定義到always塊里面,使I只對(duì)當(dāng)前塊可見。如下例:

always
begin:block1
   integer I;
for(I=0;I<32;I=I+1) begin … end
end

always
begin:block2
   integer I;
    for(I=15;I>=0;I=I-1)   begin … end
end

  在Verilog里面其它使變量本地化的方法是采用function 和task。Function和task中定義的變量只對(duì)其內(nèi)部可見。
Task send;
    Input [7:0] data;
   
    Reg   parity;
    Begin
         …
    end
endtask
function [31:0] average;
input [31:0] val1;
input[31:0] val2;
reg [32:0] sum;
begin
    sum=val1+val2;
    average=sum/2;
end
endfunction;

  另外,還要提一句關(guān)于`define VS parameter。一般設(shè)計(jì)中都要有一個(gè)頭文件,里面用`define定義了一些宏。而模塊中又有可能用parameter定義一些參數(shù)。兩者的區(qū)別是一個(gè)是全局的一個(gè)是本地的。設(shè)計(jì)者可以根據(jù)需要進(jìn)行定義。定義成本地參數(shù)避免可以避免同其他模塊的變量名字沖突。定義成全局的宏則可以在整個(gè)設(shè)計(jì)的各個(gè)文件中使用。千萬(wàn)不可為了方便全部定義成宏。

6、子程序封裝

  封裝有利于程序的可維護(hù)性。如果程序中多次用到一段代碼,應(yīng)根據(jù)實(shí)際情況盡量將它定義為function、task或module。這樣做可以減少代碼長(zhǎng)度,提高可維護(hù)行和可驗(yàn)證性。

下面以testbench為例說(shuō)明。

  通常一個(gè)SoC設(shè)計(jì)中,需要首先設(shè)計(jì)和驗(yàn)證各個(gè)子模塊,然后才進(jìn)行系統(tǒng)級(jí)驗(yàn)證,因此要多次用到testbench。每個(gè)testbench中都要初始化時(shí)鐘、進(jìn)行系統(tǒng)復(fù)位等。這些多次用到的代碼不如寫在單獨(dú)的一個(gè)文件(不妨稱作basic.v)中,各個(gè)testbench只要使用include將他們包括進(jìn)來(lái)就可以直接使用了。

  下面是我在近的863項(xiàng)目中寫的basic.v去掉一些注釋后的內(nèi)容,可以直接copy使用。

  要求將時(shí)鐘定義為clk,復(fù)位管腳定義為rst,高有效。
//start of basic.v
event ENDSIM;
// CYCLE monitor and end-of-simulation checker.
task monitor_cycles;
   input max_cycles;
   integer max_cycles;
   integer cycles;
   begin
      cycles = 0;
      fork
         // Count cycles.
         forever begin
            @(posedge clk);
            cycles = cycles + 1;
         end
        
         // Watch for max cycles.   If we detect max cycles then throw our testbench ENDSIM event.
         //
         begin
            wait (cycles == max_cycles);
            $display ("MAXIMUM CYCLES EXCEEDED!");
            ->ENDSIM;
         end
      join
   end
endtask
// Reset
task reset;
   begin
      rst = 1;
      #200;
      rst = 0;
      $display ("End RESET.");
   end
endtask

// Drive the clock input
task drive_clock;
   begin
      clk   = 0;
      forever begin
         #(`CLKLO) clk = 1;
         #(`CLKHI) clk = 0;
      end
   end
endtask

// *************   BASIC CONFIDENCE Test Tasks **************
//
// BASIC CONFIDENCE Test.
//
// This task will fork off all the other necessary tasks to cause reset, drive the clock, etc. etc.
//
//
task clk_rst_gen_and_stop_at;
   input cycle_num;
   begin
      $display ("designed by Chenxi. Email:chenxiee@mails.tsinghua.edu.cn");
      fork
         // Capture data
         capture_data;
        
         // Run the clock
         drive_clock;
        
         // Do a reset
         reset;
         begin
            monitor_cycles(cycle_num);
         end
         // Catch end of simulation event due to max number of cycles or pattern from PIC code.
         begin
            @(ENDSIM);   // Catch the event.
            $display ("End of simulation signalled.   Killing simulation in a moment.");
            #0; // Let anything else see this event...
            $stop;
         end
      join
   end
endtask
//end of basiv .v
在testbench中可以直接例化使用。
//somemodule_tb.v
module somemodule_tb;
`include “basic.v”
initial begin
// ** This is our top-level "Basic Confidence" test.

//generatr rst,clk,and stop at 5000 cycles
   clk_rst_gen_and_stop_at(5000);

end

endmodule //End of somemodule_tb.v

  需要注意的是basic.v不能夠單獨(dú)編譯。直接編譯testbench就可以了。上述方法也在可綜合的代碼中使用。
參考文獻(xiàn)[1]推薦的另外一種辦法是將上述basic.v用模塊封裝起來(lái)。如下例:
module basic;
integer warnings;
integer errors;
initial
begin
    warnings=0;
    errors=0;
end
task warning;
input[80*8:1] msg;
begin
   $write(“Warning at %t: %s”,$time,msg);
   warnings=warnings+1;
end
endtask
task terminate;
begin
$write(“Simulation Completed\n”);
$stop;
end

endmodule
調(diào)用辦法:
module somemodule_tb;
initial
begin
   …
if(…) basic.warning(”Unexpected response detected”);

basic.terminate;
end
    endmodule

7、結(jié)論

  本文VerilogHDL為例,從可重用性與可維護(hù)性的關(guān)系、代碼可擴(kuò)展性設(shè)計(jì)、盡量增加可讀性和使變量本地化、參數(shù)(parameter)和宏(`define)的對(duì)比以及封裝子程序的角度探討了可維護(hù)性設(shè)計(jì)應(yīng)遵守的幾條基本原則。



  

參考文獻(xiàn):

[1]. PCI datasheet http://www.hbjingang.com/datasheet/PCI_1201469.html.


關(guān)鍵詞:基于Verilog語(yǔ)言的可維護(hù)性設(shè)計(jì)技術(shù)Verilog語(yǔ)言

版權(quán)與免責(zé)聲明

凡本網(wǎng)注明“出處:維庫(kù)電子市場(chǎng)網(wǎng)”的所有作品,版權(quán)均屬于維庫(kù)電子市場(chǎng)網(wǎng),轉(zhuǎn)載請(qǐng)必須注明維庫(kù)電子市場(chǎng)網(wǎng),http://www.hbjingang.com,違反者本網(wǎng)將追究相關(guān)法律責(zé)任。

本網(wǎng)轉(zhuǎn)載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網(wǎng)贊同其觀點(diǎn)或證實(shí)其內(nèi)容的真實(shí)性,不承擔(dān)此類作品侵權(quán)行為的直接責(zé)任及連帶責(zé)任。其他媒體、網(wǎng)站或個(gè)人從本網(wǎng)轉(zhuǎn)載時(shí),必須保留本網(wǎng)注明的作品出處,并自負(fù)版權(quán)等法律責(zé)任。

如涉及作品內(nèi)容、版權(quán)等問題,請(qǐng)?jiān)谧髌钒l(fā)表之日起一周內(nèi)與本網(wǎng)聯(lián)系,否則視為放棄相關(guān)權(quán)利。

松夏 C語(yǔ)言 數(shù)碼管音樂噴泉 PWM直流電機(jī)調(diào)速 Proteus仿真 51單片機(jī)
廣告
OEM清單文件: OEM清單文件
*公司名:
*聯(lián)系人:
*手機(jī)號(hào)碼:
QQ:
有效期:

掃碼下載APP,
一鍵連接廣大的電子世界。

在線人工客服

買家服務(wù):
賣家服務(wù):
技術(shù)客服:

0571-85317607

網(wǎng)站技術(shù)支持

13606545031

客服在線時(shí)間周一至周五
9:00-17:30

關(guān)注官方微信號(hào),
第一時(shí)間獲取資訊。

建議反饋

聯(lián)系人:

聯(lián)系方式:

按住滑塊,拖拽到最右邊
>>
感謝您向阿庫(kù)提出的寶貴意見,您的參與是維庫(kù)提升服務(wù)的動(dòng)力!意見一經(jīng)采納,將有感恩紅包奉上哦!