FPGA/IC笔试——NVIDIA

  1.什么是建立时间、保持时间,如果setup time violation或者hold time violation 应该怎么做?

         建立时间:是指在触发器的时钟信号采样边沿到来之前,数据保持稳定不变的时间。

         保持时间:是指在触发器的时钟信号采样边沿到来之后,数据保持稳定不变的时间。

在这里插入图片描述

Timing path 时序路径分析方法: ➢ 分析时序路径时常见的变量:

Tclk = 时钟周期,是可变的,比如1KHz ~ 5.0GHz T

cq = 触发器的时钟端C到输出端Q的延时,是器件属性,是固定不变的

Tcomb = 两个触发器之间组合电路的延时,是可变的,可以通过设计进行优化逻辑

Tsetup = 建立时间是触发器的固有属性,是定值

Thold = 保持时间是触发器的固有属性,是定值

Tskew = 相邻两个触发器之间的时钟的偏移,是可变的 

在这里插入图片描述

◆ Setup time violation: ➢ 建立时间在静态时序分析时必须满足以下条件:

➢ Tclk > Tcq + Tcomb + Tsetup - Tskew

➢ 即:Tclk - Tcq - Tcomb + Tskew > Tsetup

➢ 如果setup time violation, 则上述公式不成立。

◆ Setup time violation solution:调整上述公式中的变量:Tclk, Tcomb,Tskew

➢ 增大Tclk(时钟周期):

就是降低数字系统的工作频率

➢ 减少Tcomb(组合逻辑时延):

从数字电路逻辑功能设计的角度看 » 在组合电路之间插入寄存器,增加流水线(pipeline); » 在不改变逻辑功能的前提下,对组合逻辑电路进行优化,如串行转并行; » 减少扇出或者负载; 从数字物理版图实现的角度看 » 更换速度更快的标准单元(HVT – High Voltage Threshold, SVT – Standard Voltage Threshold, LVT – Low Voltage Threshold) 高、标准、低阈值电压 » 更换驱动能力更强的标准单元(X2, X4) » 跟换阻值更低的金属层以减少标准单元电路的负载和金属线网的延迟

➢ 增加Tskew:

在时钟路径上,插入buffer,增加时钟路径的延迟,但是不能影响hold timing。

◆ Hold time violation: ➢ 保持时间在静态时序分析时必须满足以下条件: ➢ Thold < Tcq + Tcomb - Tskew ➢ 如果hold time violation, 则上述公式不成立。

◆ Hold time violation solution:

➢ 增大Tcomb

在组合电路的数据传输路径上,插入延迟单元(buffer),增加组合逻辑延迟;但是当组合逻辑 延时增加时,setup time可能会出现违例。这时候就需要做平衡(balance)。由此可以看出setup 和hold time是相互制约的。

➢ 减小Tskew

时钟树调整,做好clock tree balance,hold就容易收敛。因为hold time与时钟周期没有关系。 固有属性是在某种工艺下说的!

◆ 总结:setup和hold是相互制约的。 修复hold之后,setup的裕量就会变小或者变成负值。因此时钟频率越高,setup和hold相互制约越严重,甚至会出现修复setup之后,hold就会违例,或者修复hold之后,setup就会违例的现象。

 

2.为什么触发器会存在setup和hold time的要求?

➢ 提示:研究触发器的结构。数字电路基本结构。

3.当setup和hold time violation发生时,会导致什么后果?

➢ 提示:亚稳态

4.什么是亚稳态?如何在异步电路设计中解决亚稳态的问题?

➢ 提示:跨时钟域时,一个信号如何处理,多根信号如何处理,大量数据传输如何处理等常见的异步电路设计方法

➢ 更详细内容可参加视频课程:http://www.eecourse.com/course/103或点击跳转https://blog.csdn.net/haojie_duan/article/details/110304907

 

5.Given the following design, please draw out the waveform of output Y

在这里插入图片描述

  • 这个题目设置的s是Async preset异步置位(s=0时,输出1);还有最常见的Async reset异步复位(s=0时,输出0)

  • 参考:

在这里插入图片描述

 

6、Please improve the following design to save power

在这里插入图片描述

  • 这是涉及到低功耗设计,如果有人问你低功耗是什么,就可以简单回答:“减少0和1的翻转!”

  • 这个题目考察的门控时钟,给了使能信号,时钟就去采集数据;如果没给使能信号,就不采集(时钟就不翻转?)

在这里插入图片描述

  1. Async fifo design using Verilog

在这里插入图片描述

img

 

8.Design the schematic for the logic of New_en= eco_en ?(eco_mask ^ en): en;(Please ONLY use NAND2 cells, and try to use as less cells as possible 在这里插入图片描述

在这里插入图片描述

img

 

9、Optimize the timing paths

在这里插入图片描述

  由于两块电路里面各个输入到输出的路径延时不一致,为了避免竞争冒险必须把各个并行的路径的延时做到一样。

可以优化到的最小的延时为 2ns+0.5ns = 2.5ns. 可以通过插入反相器,与非门,或非门等。

◆ 如果只是靠插入上述的门,只能实现非,故为了保证逻辑不变必须插入偶数个。

◆ 0.1ns与2ns之间差1.9ns,是奇数个,故可以通过插入18个反相器,外加一个MUX。

◆ 0.5ns与2ns之间差1.5ns,可以插入14个反相器,外加一个mux。

◆ 后面一个电路0.1n延时的路径可以插入4个反相器。故最大延时为2.5ns。

 

10、Write verilog code which supports following function: For a string A, detect the location of its letters in string B, and output the location of the last detected letter in string B. For ample sting A is “nvidia” and string B is “naabcdiaiccbvde” the last detected letter in B is v, so output 13. 在这里插入图片描述

img

  1 //-----------------------------------------------------------
  2 // FileName: sequence_checker.v
  3 // Creator : kinglin
  4 // E-mail  : service@eecourse.com
  5 // Function: sequence checker
  6 // Update  :
  7 // Coryright: www.eecourse.com @ 2018-09-14
  8 //-----------------------------------------------------------
  9 module sequence_checker(
 10    input              clk,
 11    input              rst_n,
 12    input              in_valid,
 13    input       [7:0]  d_in,
 14    output reg  [4:0]  cout_num_s,
 15    output             o_valid
 16 );
 17   wire [7:0] stringA[0:5];
 18   //reg [8*15:1] stringB;
 19   assign stringA[0]="n";
 20   assign stringA[1]="v";
 21   assign stringA[2]="i";
 22   assign stringA[3]="d";
 23   assign stringA[4]="i";
 24   assign stringA[5]="a";
 25   //stringB="naabcdiaiccbvde";
 26   parameter idle=3'b000,
 27               s0=3'b001,  // "n"
 28               s1=3'b010,  // "nv"
 29               s2=3'b011,  // "nvi"
 30               s3=3'b100,  // "nvid"
 31               s4=3'b101,  // "nvidi"
 32               s5=3'b110;  // "nvidia"
 33   
 34   reg [2:0] next_state;
 35   reg [2:0] state;
 36   reg       out_en;
 37   reg [4:0] cout_num;
 38   //reg [4:0]cout_num_s;
 39  
 40   always @ (posedge clk or posedge rst_n) begin
 41     if(!rst_n)
 42       state <= idle;
 43     else 
 44       state <= next_state;
 45   end
 46  47   always @ (*)
 48     case(state)
 49       idle: if(d_in==stringA[0] & in_valid) begin
 50               next_state = s0;  
 51                   out_en = 1;
 52                 end else begin
 53                   next_state = idle;  
 54                   out_en = 0;
 55                 end
 56       s0:   if(d_in==stringA[1] & in_valid) begin
 57               next_state = s1;
 58                 out_en = 1;
 59               end else begin
 60                 next_state = s0;
 61                 out_en = 0;   
 62               end
 63        
 64       s1:   if(d_in==stringA[2] & in_valid) begin
 65               next_state = s2;
 66                 out_en = 1;
 67               end else begin
 68                 next_state = s1;
 69                 out_en = 0;   
 70               end
 71       s2:   if(d_in==stringA[3] & in_valid) begin
 72               next_state = s3;
 73                 out_en = 1;
 74               end else begin
 75                 next_state = s2;
 76                 out_en = 0;   
 77               end      
 78       s3:   if(d_in==stringA[4] & in_valid) begin
 79               next_state = s4;
 80                 out_en = 1;
 81               end else begin
 82                 next_state = s3;
 83                 out_en = 0;   
 84               end      
 85     s4:     if(d_in==stringA[5] & in_valid) begin
 86               next_state = s5;
 87                 out_en = 1;
 88               end else begin
 89                 next_state = s4;
 90                 out_en = 0;   
 91               end      
 92     s5:     if(d_in==stringA[0] & in_valid)begin
 93               next_state = s0;
 94                 out_en = 1;
 95               end else begin
 96                 next_state = s5;
 97                 out_en = 0;   
 98               end
 99     default:begin
100               next_state=idle;
101               out_en=0;  
102             end
103   endcase
104 
105   always @ (posedge clk or negedge rst_n) begin
106     if(!rst_n)
107       cout_num <= 5'd0;
108     else if(in_valid)
109       cout_num <= cout_num+1;
110     else 
111       cout_num <= cout_num;
112   end
113 114   always @ (posedge clk or negedge rst_n) begin
115     if(!rst_n)
116       cout_num_s <= 5'd0;
117     else if(out_en)
118       cout_num_s <= cout_num;
119     else 
120       cout_num_s <= cout_num_s;   
121   end
122 123   reg in_valid_d;
124 125   always @( posedge clk or negedge rst_n ) begin
126     if( !rst_n )
127         in_valid_d <=1'b0;
128     else
129         in_valid_d <= in_valid;
130   end  
131 132   assign o_valid = (~in_valid) & in_valid_d;  
133   
134 endmodule
 

11、c语言求解两个数组的交集和并集,并按照从小到大的顺序输出。

在这里插入图片描述

设计思想: 构建函数:1:sort排序函数,2: Intersection交集函数,3: union并集函数,4:main主函数 先对输出的两个输入数组按照从小到大的顺序排列,然后调用交集和并集函数实现运算,最后通过main主函数,打印运算的结果。

  1 #include <stdio.h>
  2 void SelectSort(int *nums,int numsSize);
  3 int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize);
  4 int* union1(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize);
  5 void SelectSort(int *nums,int numsSize){
  6    int min,temp;
  7    int i;
  8    int j;
  9    for(i=0;i<numsSize-1;i++){
 10         min=i;
 11         for(j=i+1;j<numsSize;j++){
 12             if(nums[min]>nums[j]){
 13                 min=j;
 14             }
 15         }
 16         if(min!=i){
 17             temp=nums[min];
 18             nums[min]=nums[i];
 19             nums[i]=temp;
 20         }
 21     }
 22 }
 23  24 int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) 
 25 {
 26     int temp,i,j;
 27     int *result=(int *)malloc(nums2Size*sizeof(int));
 28  29     //选择排序
 30     SelectSort(nums1,nums1Size);
 31     SelectSort(nums2,nums2Size);
 32  33     *returnSize=0;
 34     temp=nums1[nums1Size-1]+1;  //给temp赋一个不可能与nums1或nums2冲突的值
 35     for(i=0,j=0;i<nums1Size&&j<nums2Size;){
 36         if(nums1[i]>nums2[j]){
 37             j++;
 38         }
 39         else if(nums1[i]<nums2[j]){
 40             i++;
 41         }
 42         else{
 43             if(temp!=nums1[i]){
 44                 result[(*returnSize)++]=nums1[i];
 45                 temp=nums1[i];
 46             }
 47             i++;
 48             j++;
 49  50         }
 51     }
 52     return result;
 53 }
 54  55 int* union1(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize)
 56 {
 57    int temp,i,j;
 58    int *result=(int *)malloc((nums2Size+nums1Size)*sizeof(int));
 59  60    //选择排序
 61    SelectSort(nums1,nums1Size);
 62    SelectSort(nums2,nums2Size);
 63  64    *returnSize=0;
 65    temp=1000;
 66    //temp=nums1[nums1Size-1]+1;
 67     for(i=0,j=0;i<nums1Size||j<nums2Size;){
 68                 if(j!=nums2Size&&nums1[i]>nums2[j]){
 69                     result[(*returnSize)++]=nums2[j];
 70                     j++;
 71                 }
 72                 else if(i!=nums1Size&&nums1[i]<nums2[j]){
 73                     result[(*returnSize)++]=nums1[i];
 74                     i++;
 75                 }
 76         else if(j==nums2Size&&nums1[i]>nums2[j]){
 77             result[(*returnSize)++]=nums1[i];
 78                        i++;
 79         }
 80         else if(i==nums1Size&&nums1[i]<nums2[j]){
 81             result[(*returnSize)++]=nums2[j];
 82                      j++;
 83  84         }
 85         else{
 86             if(temp!=nums1[i]){
 87                 result[(*returnSize)++]=nums1[i];
 88                 temp=nums1[i];
 89             }
 90             i++;
 91             j++;
 92  93         }
 94     }
 95     return result;
 96 }
 97  98 int main(int argc, char *argv[])
 99 {
100     int a[11]={1,2,3,4,5,6,7,8,9,10,11};
101     int i;
102     int b[10]={3,4,5,6,7,8,9,10,11,12};
103     int c=0;
104     int *p=intersection(&a[0],11,&b[0],10,&c);
105 106     printf("\n +++++ array a :\n");
107     for (i=0; i<11; i++) {
108       printf("%d\n", a[i]);
109     }
110 111     printf("\n +++++ array b :\n");
112     for (i=0; i<10; i++) {
113       printf("%d\n", b[i]);
114     }
115     
116     printf("++++++ intersection of the array a & b\n");
117     for(i=0;i<c;){
118       printf("%d\n",p[i]);
119       i++;
120     }
121 122     int *p1=union1(&a[0],11,&b[0],10,&c);
123     printf("++++++ union1 of the array a & b\n");
124     for(i=0;i<c;){
125       printf("%d\n",p1[i]);
126       i++;
127     }
128     return 0;
129 }
130

 


posted on 2021-04-28 10:26  一曲挽歌  阅读(643)  评论(0编辑  收藏  举报

导航