10-经典组合和时序电路

经典组合和时序电路

HDL的主流语言

  • VHDL
  • Verilog
  • System Verilog
    硬件描述层次
  • 门级(gate-level)
  • 寄存器传输级(RTL-Level)
  • 行为级
    RTL:Register Transfer Level
  • 可综合性,写的代码要可综合
  • 可阅读性,划分模块,增加代码的可阅读性

全加器

module fulladder(cout,sum,ain,bin,cin);
  
  input ain,bin,cinl=;      //定义端口
  output sum,cout;
  wire sum;                // 定义变量
  wire cout;
  
  assign sum = ain ^ bin ^ cin;        // 主体
  assign cout = (ain & bin)|(bin & cin)|(ain & cin);
  
endmodule

四选一选择器

module mux_4_1(C,D,E,F,S,Mux_out);
  input C,D,E,F;
  input [1,0] S; 
  output Mux_out;
  
  reg Mux_out;
  
  always@(C,D,E,F,S)
  begin
    case(S)
      2'b00 : Mux_out = C;
      2'b01 : Mux_out = D;
      2'b02 : Mux_out = E;
      default : Mux_out = F;
    endcase
  end

endmodule
  • 敏感列表中只要有一个信号发生变化,就会启动begin end
  • 使用always@(*) -- * 表示所有的输入
  • assign -- 使用wire类型

3-8译码器

module 3_8_Decoder(
  input wire [2:0] ain,  //三位开关
  input wire       enable,     //50Hz
  output reg [7:0] yout
);

  always@(ain or enable) begin
    if(!enable) 
      yout = 8'b0
    else 
      case(ain)
        3'b000 : yout = 8'b00000001;
        3'b001 : yout = 8'b00000010;
        3'b010 : yout = 8'b00000100;
        3'b011 : yout = 8'b00001000;
        3'b100 : yout = 8'b00010000;
        3'b101 : yout = 8'b00100000;
        3'b110 : yout = 8'b01000000;
        default : yout = 8'b10000000;
      endcase
  end  
endmodule
  • one-hot -- 输出的代码中只有一个为1

计数器

module count_en (enable,clock,reset,out);
  paramet er WIDTH = 8;
  Parameter UDLY  = 1;
  
  input clock,reset,enable;
  output [WIDTH-1:0] out;
  
  reg [WIDTH-1:0] out;

  always @ (posedge clock,negedge reset) begin
    if(!reset)
      out <= 8'b0;
    else if (enable)
      out <= #UDLY out+1
  end
endmodule
  • 时序逻辑的信号是reg或者是logic
  • 时序逻辑的信号是可以保持的
  • 寄存器一定要写enable,减少能耗
  • D端传输信号到Q端会有延迟信息
  • 异步复位可以理解为复位信号与时钟信号无关

逻辑操作

移位器

module shifter 
#(parameter B = 2)
(
  input [3:0] data,
  output reg [3:0] q1,q2
);

  always @ (data) begin
    q1 = data << B;
    q2 = data >> B;
  end
endmodule

D触发器的写法

module dff_async_pre
#(parameter U_DLY = 1)
(
  input data,clk,preset,
  output q
);
  always @ (posedge clk , negedge preset) begin
    if(~preset)
      q <= #U_DLY 1'b1;
    else
      q <= #U_DLY data;
  end
endmodule

同步复位的DFF


module dff_sync_pre
#(parameter U_DLY = 1)
(
  input data,clk,preset,
  output q
);
  always @ (posedge clk) begin
    if(~preset)
      q <= #U_DLY 1'b1;
    else
      q <= #U_DLY data;
  end
endmodule

带有异步复位和异步置位DFF

module dff_async_pre
#(parameter U_DLY = 1)
(
  input data,clk,preset,reset,
  output q
);
  always @ (posedge clk , negedge preset,reset) begin
    if(~preset)
      q <= #U_DLY 1'b1;
    else if (reset)
      q <= 1'b1;
    else
      q <= #U_DLY data;
  end
endmodule
  • 既能复位又可以置位的DFF,都有时钟无关

Testbench搭建

testbench的功能

  • RM - reference module
  • golden - 正确结果
  • 验证三要素:灌激励\集响应\做比较

tb实例

  1. 定义tb,写在一个没有输入的module中

  2. 定义时钟
    常用的写法
initial begin
   Clk = 0;
   forever #10 Clk = ~Clk;
end
  1. 例化DUT
  2. 生成激励
  3. 采集响应
  4. 调试bug
    7.verdi查看波形时的函数
initial begin
  $fsdbDumpfiles("./sim.fsdb");
  $fsdbDumpvars(0,top);
end
// Makefile文件
FLIST := ../rtl/adder32.v\
         ../tb/adder_tb.v

run:
  vcs -sverilog $(FLIST) -debug_all -P ${NOVAS_HOME}/share/PLI/VCS/LINUX/novas.tab ${NOVAS_HOME}/share/PLI/VCS/LINUX/pli.a -R -kdb -lca

wave:
  verdi -simflow -elab simv.daidir/kdb.elab++ -ssf sim.fsdb

clean
  rm csrc novas_dump.log sim.fsdb simv simv.daidir ucli.key verdi_config_file novas.conf novas.rc verdiLog -rf
posted @ 2023-02-12 12:07  Icer_Newer  阅读(53)  评论(0编辑  收藏  举报