Example Image´ó·¢28

³É¶¼Ïßϰà 2ÔÂ24ºÅ¿ª°à
ÖØÇìÏßϰà 3ÔÂ24ºÅ¿ª°à
¹ã¶«Ïßϰà 5ÔÂ24ºÅ¿ª°à
짃졈
ÆóÒµÅàѵ
FPGAÖ¤Ê鱨Ãû
FPGA¹¤³ÌʦÕÐÆ¸
½üÆÚÓÅ»ÝÔ˶¯
ÔÚÏ߿ͷþ
΢ÐŶþάÂë

΢Ðſͷþ

ɨÂëÌí¼Ó¿Í·þ΢ÐÅ

FPGAÖ¤Ê鱨Ãû

FPGA¹¤³ÌʦӦƸ

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

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

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

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

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

¼¼ÇÉ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ÆßÈÕ½ø½×ѵÁ·ÓªÊÔÌýÁ´½Ó]

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

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

¡¾ÍøÕ¾µØÍ¼¡¿¡¾sitemap¡¿