数字IC笔试题(5)

学习摘自数字芯片实验室

Nvidia前端设计2018
1、什么是建立时间、保持时间?如果setup time violation或者hold time violation应该怎么做?
在这里插入图片描述

建立时间:在触发器的时钟信号边沿来临之前,数据稳定不变的时间

保持时间:在触发器的时钟信号边沿来临之后,数据稳定不变的时间

在这里插入图片描述

setup time :

Tclk - Tco – Tcomb + Tskew > Tsu

根据上述公式,解决setup violation,可以从一下角度考虑:

1、Tclk(时钟周期) : 增加Tclk,即降频

2、Tcomb(触发器之间组合逻辑延时): 减小Tcomb,即优化关键路径组合逻辑,减小负载,或者增加一个触发器来分割组合逻辑延时

3、Tskew(触发器之间时钟偏移):增加Tskew,即增加时钟路径的skew,可能会影响hold time violation

4、Tco 和 Tsu (库中器件固定属性):更换更快的标准单元库,即hvt - > lvt。

hold time :

Tco + Tcomb – Tskew > Thold

根据上述公式,解决hold violation,可以从一下角度考虑:

1、Tcomb :增加Tcomb,即增加组合逻辑延时,插入buffer。可能会影响setup violation

2、Tskew :减小Tskew,做好时钟树的balance

2、 Giventhe following design ,please draw out the waveform of outout Y.

在这里插入图片描述

其中,S= Async preset,异步置位

module demo(
    input D ,
    input CLK ,
    input S ,
    output  Y );
    
    reg  Q ;
    always@(posedge CLK or negedge S ) begin
        if(~S) begin 
            Q <= 1'b1 ;
        end
        else begin
            Q <= D ;
        end
    end
    
    assign Y =  D && Q ;


endmodule
module demo_tb;
    reg D  ;
    reg CLK ;
    reg S ;
    wire Y ;
demo demo(
    .D(D),
    .CLK(CLK),
    .S(S),
    .Y(Y)
); 
initial begin
    CLK = 0 ;
    S = 0 ;
    #6 S= 1 ;
    #52.5 S = 0 ;
end

initial begin
    D = 0 ;
#16 D = 1 ;
#20 D = 0 ;
#30 D =1 ;
#4   D = 0 ;
end
    always #5 CLK =~CLK ;

endmodule

在这里插入图片描述
3、Pleaseimprove the following design to save power

在这里插入图片描述

时钟门控

En = 1’b0 时,可以关闭时钟触发,减少动态功耗

在这里插入图片描述

题目电路仿真及功耗分析:
在这里插入图片描述
在这里插入图片描述

门控后仿真及功耗分析:

在这里插入图片描述
在这里插入图片描述

4、 Asyncfifo design using Verilog

Design:

module  asyn_fifo(
  input wclk ,
  input rst_n ,
  input wr_en ,
  input [7 : 0] data_in ,
  output full ,
  
  input rclk ,
  input rd_en ,
  output reg [7:0]  data_out ,
  output empty
);


reg [7 : 0 ] mem[7 : 0] ;
wire [2:0]   r_addr , w_addr ;
reg [3:0]   binary_r_addr , binary_w_addr ;
wire [3:0]   gray_r_addr , gray_w_addr ;
reg [3:0]   gray_r_addr_reg , gray_w_addr_reg ;


assign gray_r_addr =   ( binary_r_addr >> 1 ) ^ binary_r_addr;
assign gray_w_addr =   ( binary_w_addr >> 1 ) ^ binary_w_addr;
assign r_addr = gray_r_addr[2:0] ;
assign w_addr = gray_w_addr[2:0] ;


always@(posedge rclk or negedge rst_n ) begin
  if(~rst_n) begin
    binary_r_addr <= 4'b0 ;
    gray_w_addr_reg <= 4'b0 ;
    data_out <= 8'b0 ;
  end
  
  
  else begin
    gray_w_addr_reg <=   gray_w_addr ;
    if(rd_en == 1'b1 && empty == 1'b0) begin
      data_out <= mem[r_addr] ;
      binary_r_addr <= binary_r_addr + 1'b1 ;
    end
  end
end


always@(posedge wclk or negedge rst_n) begin
  if(~rst_n) begin
    binary_w_addr <= 4'b0 ;
    gray_r_addr_reg <= 4'b0 ;
  end
  else begin
    gray_r_addr_reg <= gray_r_addr ;
    if(wr_en == 1'b1 && full == 1'b0 )begin
      mem[w_addr] <= data_in ;
      binary_w_addr <= binary_w_addr + 1'b1 ;
    end
  end
end


assign empty = (gray_r_addr == gray_w_addr_reg) ? 1:0 ;
assign full = ( (gray_w_addr[3] !== gray_r_addr_reg[3]) && (gray_w_addr[2] !== gray_r_addr_reg[2]) &&(gray_w_addr[1:0] == gray_r_addr_reg[1:0]) ) ? 1:0 ;


endmodule

Testbench:

`timescale 1ns/1ns
module async_fifo_tb;
  reg rst_n;
  reg wr_en ;
  reg rclk;
  wire [7:0] data_out;
  wire full ;
  
  
  reg [7:0] data_in;
  reg wclk ;
  reg rd_en ;
  wire empty;
  
  
  asyn_fifo asyn_fifo(
    .wclk(wclk) ,
    .rst_n(rst_n) ,
    .wr_en(wr_en) ,
    .data_in(data_in) ,
    .full(full) ,
    .rclk(rclk) ,
    .rd_en(rd_en) ,
    .data_out(data_out) ,
    .empty(empty)
  );
  
  
  initial begin
      rst_n=1;
      rclk=0;
      wclk=0;
      #1 rst_n=0;
      #5 rst_n=1;
   end
   initialbegin 
      wr_en=0;
      #1 wr_en=1;
      end
      initial
      begin    
      rd_en=0;
      #650 rd_en=1;
      wr_en=0;
    end
  
  
  always #30 rclk=~rclk;
  always #20 wclk=~wclk;
  initial begin
    data_in=8'h0;
    #40 data_in=8'h1;
    #40 data_in=8'h2;
    #40 data_in=8'h3;
    #40 data_in=8'h4;
    #40 data_in=8'h5;
    #40 data_in=8'h6;
    #40 data_in=8'h7;
    #40 data_in=8'h8;
    #40 data_in=8'h9;
    #40 data_in=8'ha;
    #40 data_in=8'hb;
    #40 data_in=8'hc;
    #40 data_in=8'hd;
    #40 data_in=8'he;
    #40 data_in=8'hf;
    #1600 $finish;
  end
  
  
endmodule

fifo写数据:
在这里插入图片描述

fifo读数据:
在这里插入图片描述
5、Design theschematic for the logic of New_en = eco_en ? (eco_mask ^ en) : en;

(Please ONLY use NAND2 cells ,and tryto use as less cells as possible)

数字电路卡诺图化简

用2输入与非门构成任意组合逻辑,这也是工具基于标准单元库进行逻辑综合的理论基础

了解逻辑综合之后,也就知道大学数字电路出这种题目的意义了。

6、Optimize thetiming paths from IN* to OUT.You can use inverter,nand2,nor2 and mux,assuming0.1ns delay ve the longest delay after optimization.

Hint :you cannot change logic insidethe boxes.

在这里插入图片描述
没看懂

7、Write verilog code which supports followingfunction:For a string A ,detect the location of its letters in string B ,and output the location of thelast detectedletter in string B.For example :string Ais “nvidia” and string B is “naabcdiaiccbvde”,the last detected letter in B isv , so output 13.

Design

module sequence_detect(
input              clk,
input              rst_n,
input       [7:0]  stringB_in,
input              stringB_en ,
input              stringB_over ,
output reg  [4:0]  location,
output reg           out_valid
);




reg [4:0] location_reg_count;
always @ (posedge clk or negedge rst_n) begin
  if(!rst_n)
    location_reg_count <= 5'd0;
  else if(stringB_en == 1'b1 && stringB_over == 1'b0) begin
    location_reg_count <= location_reg_count+1;
  end
end



reg [4:0] location_reg;
always @ (posedge clk or negedge rst_n) begin
  if(!rst_n)
    location_reg <= 0;
  else if (stringB_en == 1'b1 && stringB_over == 1'b0 ) begin
    if(stringB_in == "n" || stringB_in == "v" || stringB_in == "i"  ||stringB_in == "d"  || stringB_in == "a") begin
      location_reg <= location_reg_count ;
    end
    else begin
      location_reg <= location_reg ;
    end
  end
end


always @ (posedge clk or negedge rst_n) begin
  if(!rst_n)
    out_valid <= 0;
  else if (stringB_over == 1'b1 ) begin
    location <= location_reg ;
    out_valid <= 1'b1;
  end
  else begin
    location <= 0 ;
    out_valid <= 1'b0;
  end
end
      

endmodule

Testbench:

`timescale 1ns/1ps
module sequence_detect_tb;


reg   clk;
reg   rst_n;
reg   stringB_en ;
reg   stringB_over ;
reg  [7:0] stringB_in;
wire [4:0] location;
wire out_valid;


// instance of the DUT
sequence_detect sequence_detect(
.clk(clk),
.rst_n(rst_n),
.stringB_in(stringB_in),
.stringB_en(stringB_en),
.stringB_over(stringB_over) ,
.location(location),
.out_valid(out_valid)
);


always #5 clk = ~clk;



initial begin
clk    = 1'b0;
rst_n  = 1'b1;
stringB_en = 1'b0;
  stringB_over = 1'b0 ;
  stringB_in = "0"  ;


#100 rst_n = 1'b0;
#100 rst_n = 1'b1;
stringB_en = 0;
end
initial begin
end




initial begin
#300 ;
stringB_en = 1;
#1 stringB_in = "n"  ;
@(posedge clk ) ;
#1 stringB_in = "a"  ;
@(posedge clk ) ;
#1 stringB_in = "a"  ;
@(posedge clk ) ;
#1 stringB_in = "b"  ;
@(posedge clk ) ;
#1 stringB_in = "c"  ;
@(posedge clk ) ;
#1 stringB_in = "d"  ;
@(posedge clk ) ;
#1 stringB_in = "i"  ;
@(posedge clk ) ;
#1 stringB_in = "a"  ;
@(posedge clk ) ;
#1 stringB_in = "i"  ;
@(posedge clk ) ;
#1 stringB_in = "c"  ;
@(posedge clk ) ;
#1 stringB_in = "c"  ;
@(posedge clk ) ;
#1 stringB_in = "b"  ;
@(posedge clk ) ;
#1 stringB_in = "v"  ;
@(posedge clk ) ;
#1 stringB_in = "d"  ;
@(posedge clk ) ;
#1 stringB_in = "e"  ;
@(posedge clk ) ;
#1 stringB_in = "0"  ;
@(posedge clk ) ;
  stringB_over = 1'b1 ;



end


initial begin
#1000 $finish;
end


endmodule

在这里插入图片描述

发布了32 篇原创文章 · 获赞 2 · 访问量 1511

猜你喜欢

转载自blog.csdn.net/qq_36248682/article/details/105291796