ExASIC
分享让工作更轻松

极简Verilog可综合教程

Verilog HDL如其名——硬件描述语言,是用来描述硬件电路的。可以分为两类:组合逻辑和时序逻辑。所以下面是常用的描述电路的核心Verilog语法介绍及举例。

组合逻辑

assign

wire [3:0] dat_out;
assign dat_out = dat_en ? dat_in : 4'b0;

always

reg [3:0] dat_out;
always@(*)
  if(dat_en)
    dat_out = dat_in;
  else
    dat_out = 4'b0;

时序逻辑

reg [3:0] dat_out;
always@(posedge clk, negedge rst_n)
  if(!rst_n)
    dat_out <= 4'b0;
  else if(dat_en)
    dat_out <= dat_in;

实例

组合逻辑:3-8译码器

module decode38
  (
  input wire [2:0] dat_in,
  output wire [7:0] dat_out
  );

  assign dat_out = dat_in == 3'b000 ? 8'b0000_0001 :
                   dat_in == 3'b001 ? 8'b0000_0010 :
                   dat_in == 3'b010 ? 8'b0000_0100 :
                   dat_in == 3'b011 ? 8'b0000_1000 :
                   dat_in == 3'b100 ? 8'b0001_0000 :
                   dat_in == 3'b101 ? 8'b0010_0000 :
                   dat_in == 3'b110 ? 8'b0100_0000 :
                   8'b1000_0000;

endmodule // decode38

也可以用case语句来实现,如下:

module decode38
  (
  input wire [2:0] dat_in,
  output reg [7:0] dat_out
  );

  always@(*)
    case(dat_in)
    3'b000: dat_out = 8'b0000_0001;
    3'b001: dat_out = 8'b0000_0010;
    3'b010: dat_out = 8'b0000_0100;
    3'b011: dat_out = 8'b0000_1000;
    3'b100: dat_out = 8'b0001_0000;
    3'b101: dat_out = 8'b0010_0000;
    3'b110: dat_out = 8'b0100_0000;
    3'b111: dat_out = 8'b1000_0000;
    default: dat_out = 8'b0000_0001;
    endcase

endmodule // decode38  

时序逻辑:状态机

module sm
  (
  input wire clk,
  input wire rst_n,

  input wire start_condition,
  input wire done_condition,

  output reg st_start,
  output reg st_busy
  );

  reg [3:0] st_cs; //current state of state machine
  reg [3:0] st_ns;

  //define local state parameters
  localparam IDLE  = 4'd0;
  localparam START = 4'd1;
  localparam RUN   = 4'd2;
  localparam DONE  = 4'd3;

  // 1st part of state machine
  always@(posedge clk, negedge rst_n)
    if(!rst_n)
      st_cs <= IDLE;
    else
      st_cs <= st_ns;

  // 2nd part of state machine
  always@(*)
    case(st_cs)
    IDLE:
    if(start_condition)
      st_ns = START;
    else
      st_ns = IDLE;
    START:
      st_ns = RUN;
    RUN:
    if(done_condition)
      st_ns = DONE;
    else 
      st_ns = RUN;
    DONE:
      st_ns = IDLE;
    default: st_ns = IDLE;
    endcase //st_cs

  // 3rd part of state machine
  always@(posedge clk, negedge rst_n)
    if(!rst_n)
      st_start <= 1'b0;
    else if(st_cs == START)
      st_start <= 1'b1;
    else
      st_start <= 1'b0;

  always@(posedge clk, negedge rst_n)
    if(!rst_n)
      st_busy <= 1'b0;
    else if(st_cs != IDLE)
      st_busy <= 1'b1;
    else
      st_busy <= 1'b0;

endmodule // sm

总结

语法大概就这么多了,剩下的只是灵活应用了。

阅读数:
更多文章:文章目录
解惑专区
(支持markdown插入源代码)
欢迎使用ExASIC订阅服务
仅用于ExASIC最新文章通知,方便及时阅读。
友情链接: 白山头NingHeChuanShuang'Blog
成都奥卡思微电科技有限公司,主要产品有AVE自动化验证工具软件和MegaEC等价验证工具软件。硅知识,上海市集成电路高技能人才培养基地NanDigits中国,主要产品GOF。2020年元旦,我们,十多位IC行业的公众号号主,共同建立了一个 “ IC技术圈 ” 。我们将在这里或分享经验,或传授技巧,或聊求职就业,或谈人生规划。陕西纳宇测量设备有限公司AD