Example Image´ó·¢28

ÔÚÕâÀï¸æËßÎÒÃÇÄúµÄÐèÇó°É

ÎÒÃÇ¿ÉÒÔ¸ü¿ìµÄÏàʶÄúµÄÐèÇó
ÆóÒµÈ˲ÅÕÐÆ¸ÐèÇó·´Ïì

È˲ÅÐèÇó


ÁªÏµÈË&ÁªÏµ·½·¨


ÔÚÕâÀï¸æËßÎÒÃÇÄúµÄÐèÇó°É

ÎÒÃÇ¿ÉÒÔ¸ü¿ìµÄÏàʶÄúµÄÐèÇó
ÆóÒµÍÅÅà±íµ¥
´ó·¢28¡¤(ÖйúÓÎ)¹Ù·½ÍøÕ¾

FPGA¹¤³Ìʦ±Ø¶®µÄ10¸öVerilog±àÂë¼¼ÇÉ£ºÐ´³ö¸ßЧ¿É¿¿µÄÓ²¼þ´úÂë

FPGA¹¤³Ìʦ±Ø¶®µÄ10¸öVerilog±àÂë¼¼ÇÉ£ºÐ´³ö¸ßЧ¿É¿¿µÄÓ²¼þ´úÂë

СÐò£ºÎªÊ²Ã´ÄãµÄVerilog´úÂë×ÜÊÇ¡°ÅÜÇ·ºà¡±£¿£¿£¿£¿ £¿

ÔÚFPGA¿ª·¢ÖУ¬£¬ £¬50%µÄʱÐòÎÊÌâÔ´ÓÚÔã¸âµÄ±àÂëϰ¹ß¡£¡£¡£±¾ÎÄ´ÓÆóÒµ¼¶´úÂë¹æ·¶³ö·¢£¬£¬ £¬ÌáÁ¶³ö10¸öÁ¢¸Í¼ûÓ°µÄVerilog±àÂë¼¼ÇÉ£¬£¬ £¬ÅäºÏÕæÊµ¹¤³Ì°¸Àý£¬£¬ £¬ÖúÄã¹æ±Ü³£¼ûÏÝÚ壬£¬ £¬ÌáÉý´úÂëÖÊÁ¿¡£¡£¡£
ÎÄÄ©Ãâ·ÑÁìÈ¡¡¶Verilog´úÂë¹æ·¶¼ì²é±í¡·PDF£¨º¬Xilinx/AlteraË«°æ±¾£©£¬£¬ £¬Ò»¼üÅŲé´úÂëÒþ»¼£¡

Comparison animation: latch generation vs combinational logic

Ò»¡¢ÃüÃû¹æ·¶£ºÈôúÂë×ÔÎĵµ»¯

¼¼ÇÉ1£ºÄ£¿£¿£¿£¿ £¿é/ÐźÅÃüÃû×ñÕÕ¡¸¹¦Ð§+Æ«Ïò¡¹Ô­Ôò

verilog

// ? Ôã¸âʾÀý
wire a, b, c; 

// ? ÓÅ»¯Ê¾Àý
wire [7:0] adc_data_in;  // À´×ÔADCµÄ8λÊäÈëÊý¾Ý
wire       uart_tx_en;    // UART·¢ËÍʹÄÜÐźÅ

ÆóÒµ¹æ·¶£º

  • ÊäÈëÐźźó׺_in£¬£¬ £¬Êä³öÐźźó׺_out
  • ʱÖÓÐźÅͳһÃüÃûclk_<¹¦Ð§>£¬£¬ £¬¸´Î»ÐźÅrst_<×÷ÓÃÓò>_n£¨µÍÓÐÓã©

¶þ¡¢Ê±ÐòÂß¼­Éè¼Æ£ºËø´æÆ÷ÊÇÑý¹Ö£¡

¼¼ÇÉ2£ºalways¿é±ØÐèÍêÕûÁýÕÖÌõ¼þ·ÖÖ§

verilog

// ? ±¬·¢Ëø´æÆ÷£¡
always @(*) begin
    if (sel)
         out = a;
    // ȱÉÙelse·ÖÖ§£¡
end 

// ? Ç徲д·¨£º²¹È«default
always @(*) begin
    if (sel)
         out = a;
    else
            out = 8'hFF; // Ã÷ȷĬÈÏÖµ
end

? ±ÈÕÕ¶¯Í¼£º
Ëø´æÆ÷ÌìÉú vs ÍêÕûÌõ¼þÁýÕÖ
£¨×󣺲»ÍêÕûÌõ¼þµ¼ÖÂËø´æÆ÷£»£»£»£»ÓÒ£º²¹È«·ÖÖ§ÌìÉú´¿×éºÏÂß¼­£©

Èý¡¢¸´Î»²ßÂÔ£ºÍ¬²½¸´Î» vs Òì²½¸´Î»

¼¼ÇÉ3£ºÈ«¾ÖʹÓÃͬ²½¸´Î»£¬£¬ £¬¾Ö²¿ÉóÉ÷ÓÃÒì²½

verilog

// ? ͬ²½¸´Î»±ê׼д·¨
always @(posedge clk) begin
    if (rst_n) begin
        cnt <= 8'b0;
    end else begin
        cnt <= cnt + 1;
    end
end

 // ?? Òì²½¸´Î»½öÓÃÓÚÌØÊⳡ¾°£¨ÈçʱÖÓ»Ö¸´£©
always @(posedge clk or negedge async_rst_n) begin
    if (!async_rst_n)
         state <= IDLE;
    else
         state <= next_state;
end

Òªº¦µã£º

  • Xilinx FPGAÓÅÏÈÓÃͬ²½¸´Î»£¨ïÔÌ­²¼Ïß×ÊÔ´Õ¼Óã©
  • Òì²½¸´Î»Ðè×ö¸´Î»Í¬²½Æ÷Ïû³ýÑÇÎÈ̬

ËÄ¡¢¸³Öµ·½·¨£ºÛÕ±Õ vs ·ÇÛÕ±Õ

¼¼ÇÉ4£º×éºÏÂß¼­ÓÃÛÕ±Õ(=)£¬£¬ £¬Ê±ÐòÂß¼­Ó÷ÇÛÕ±Õ(<=)

verilog

// ? »ìÏý¸³Öµµ¼Ö·ÂÕæÓë×ÛºÏ·×ÆçÖÂ
always @(posedge clk) begin
    a = b + c;  // ÛÕ±Õ¸³Öµ
    d <= a;      // ·ÇÛÕ±Õ¸³Öµ
end

// ? ÑÏ¿áÇø·ÖʹÓó¡¾°
// ʱÐòÂß¼­
always @(posedge clk) begin
    data_ff <= data_in;  // ·ÇÛÕ±Õ
end

// ×éºÏÂß¼­
always @(*) begin
    sum = a + b;         // ÛÕ±Õ
end

Î塢״̬»úÉè¼Æ£ºÈý¶ÎʽÊÇÇ广½äÂÉ

¼¼ÇÉ5£ºÓÃparameter½ç˵״̬£¬£¬ £¬Èý¶Îʽ½á¹¹ÇåÎú

verilog

// ? ±ê×¼Èý¶Îʽ״̬»ú
localparam S_IDLE = 3'b001,
           S_RUN  = 3'b010,
           S_DONE = 3'b100;

 // µÚÒ»¶Î£º×´Ì¬¼Ä´æÆ÷
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        state <= S_IDLE;
    else
         state <= next_state;
end

// µÚ¶þ¶Î£ºÏÂһ״̬Âß¼­
always @(*) begin
    case(state)
        S_IDLE: next_state = start ? S_RUN : S_IDLE;
        S_RUN:  next_state = (cnt == 10) ? S_DONE : S_RUN;
        S_DONE: next_state = S_IDLE;
        default:next_state = S_IDLE;
    endcase
end

// µÚÈý¶Î£ºÊä³öÂß¼­
always @(posedge clk) begin
    if (state == S_RUN)
        cnt <= cnt + 1;
    else
         cnt <= 0;
end

Áù¡¢caseÓï¾ä£ºÓÅÏȼ¶ÏÝÚå

¼¼ÇÉ6£ºcasex/casezÉóÉ÷ʹÓ㬣¬ £¬ÓÅÏÈÓÃfull case

verilog

// ? casex¿ÉÄܵ¼ÖÂÒâÍâÆ¥Åä
casex (sel)
    4'b1??? : out = a;c// ¿ÉÄÜÆ¥Åäµ½sel=1000ÒÔÍâµÄÖµ
endcase

// ? Ìí¼Ódefault²¢ÏÞÖÆÆ¥Å乿ģ
case(sel[3:1])  // Ã÷È·Æ¥Åäλ¿í
    3'b100: out = a;
    default:out = 8'h00;
endcase

ÆóÒµ¹æ·¶£º

  • ×ÛºÏǰÉèÖÃfull_caseºÍparallel_case×èÖ¹Ëø´æÆ÷
  • ʹÓÃuniqueºÍpriorityÒªº¦×Ö£¨SystemVerilog£©

Æß¡¢Ä£¿£¿£¿£¿ £¿é»¯Éè¼Æ£º¾Ü¾ø¡°¾ÞÎÞ°Ô¡±Ä£¿£¿£¿£¿ £¿é

¼¼ÇÉ7£º¼òµ¥Ä£¿£¿£¿£¿ £¿é²»Áè¼Ý200ÐдúÂë

verilog

// ? ¹¦Ð§²ð·ÖʾÀý
module uart_tx (
    input  clk,
    input  [7:0] data_in,
    output txd
);

module uart_rx (
    input  clk,
    input  rxd,
    output [7:0] data_out
);

// ¶¥²ãÄ£¿£¿£¿£¿£¿é½öÀý»¯
module top;
    uart_tx u_tx(...);
    uart_rx u_rx(...);
endmodule

ÓÅÊÆ£º

  • ±ãÓÚ¸´Óú͵¥Î»²âÊÔ
  • ½µµÍ×ÛÊÊʱ¼ä£¨ÔöÁ¿±àÒ룩

°Ë¡¢×¢Ê͹淶£º²»ÊÇ¡°Ð´Ê²Ã´¡±£¬£¬ £¬¶øÊÇ¡°ÎªÊ²Ã´¡±

¼¼ÇÉ8£º×¢ÊÍÚ¹ÊÍÉè¼ÆÒâͼ£¬£¬ £¬¶ø·ÇÖØ¸´´úÂë

verilog

// ? ÎÞЧעÊÍ
reg [3:0] cnt; // ½ç˵4λ¼ÆÊýÆ÷ 

// ? ÓмÛÖµ×¢ÊÍ
// ²¨ÌØÂÊ·ÖÆµ¼ÆÊýÆ÷£º115200bps @ 50MHz
// ·ÖƵÊý = 50e6 / (115200 * 16) ¡Ö 27
reg [4:0] baud_cnt; // ÐèÁýÕÖ0-26£¨5λ×ã¹»£©

¾Å¡¢·ÂÕæÓë×ۺϣºÌáǰ·¢Ã÷·×ÆçÖÂ

¼¼ÇÉ9£ºÒªº¦Â·¾¶Ìí¼Ótranslate_off×¢ÊÍ

verilog

// ·Âտ׍ÓôúÂ루²»¼ÓÈë×ۺϣ©
// synopsys translate_off
initial begin
    $dumpfile("wave.vcd");
    $dumpvars(0, tb_module);
end
// synopsys translate_on

¹¤¾ßÁ´ÏÂÁ

  • Xilinx:?set_property -name {STEPS.SYNTH_DESIGN.ARGS.MORE OPTIONS} -value "-verilog_define SIMULATION" -objects [get_runs synth_1]

Ê®¡¢´úÂëÓÅ»¯£º×ÊÔ´ÓëËÙÂÊµÄÆ½ºâ

¼¼ÇÉ10£ºÓÃλ¿í²Ã¼ôÌæ»»³ý·¨

verilog

// ? Ö±½ÓʹÓóý·¨ÔËËã·û
reg [31:0] div = data_in / 10; // ×ۺϳÉDSP48µ¥Î» 

// ? λ²Ù×÷½üËÆÅÌË㣨Îó²î<1%£©
// ³ýÒÔ10 ¡Ö ÓÒÒÆ3루¡Â8£© + µ÷½âÅâ³¥
wire [31:0] div_opt = (data_in >> 3) + (data_in >> 5) - (data_in >> 7);

? ±ÈÕÕ¶¯Í¼£º
³ý·¨Æ÷×ÊÔ´Õ¼ÓñÈÕÕ
£¨×ó£ºÖ±½ÓŲÓóý·¨Æ÷ÏûºÄ18¸öDSP£»£»£»£»ÓÒ£ºÎ»²Ù×÷½öÓÃÂß¼­×ÊÔ´£©

¸£ÀûÁìÈ¡

Á¢¼´»ñÈ¡¡¶Verilog´úÂë¹æ·¶¼ì²é±í¡·PDF£¬£¬ £¬°üÀ¨£º

  • Xilinx/Altera±àÂë¹æ·¶²î±ð±ÈÕÕ±í
  • ¿É´òÓ¡µÄ´úÂëÉó²éÇåµ¥£¨Code Review Checklist£©
  • 20¸ö³£¼û¹ýʧ°¸Àý¼°ÐÞ¸´ÒªÁì

ÑÓÉìѧϰ£ºVerilogÆßÈÕ½ø½×ѵÁ·Óª

ÈôÊÇÄãÏ£Íû£º
? ÕÆÎÕÆóÒµ¼¶FPGA´úÂë¹æ·¶
? Ç×ÊÖÍê³ÉǧÕ×ÒÔÌ«Íø¼ÓËÙÆ÷ÏîÄ¿
? »ñµÃ»ªÎª/ÖÐÐË×ÊÉ³Ìʦ´úÂëÆÀÉó

Á¢¼´Ãâ·ÑÊÔÌý?? [VerilogÆßÈÕ½ø½×ѵÁ·ÓªÊÔÌýÁ´½Ó]

Verilog code snippet showing case statement usage

ͨ¹ý¹æ·¶±àÂ룬£¬ £¬ÈÃÄãµÄ´úÂëÒ»´Î±àд£¬£¬ £¬ÖÕÉíÊÜÓã¡

´ó·¢28¡¤(ÖйúÓÎ)¹Ù·½ÍøÕ¾
¡¾ÍøÕ¾µØÍ¼¡¿¡¾sitemap¡¿