数字IC笔试题 ——Nvidia前端设计2018

 

4、 Asyncfifo design using Verilog

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

 

 

 

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

 

#include <stdio.h>
#include "malloc.h"
void NumSort(int *number, int numbersize);


int *intersection_numbers(int *number1, int numbersize1, int *number2, int numbersize2,int *intersection_size);
int *union_numbers(int *number1, int numbersize1, int *number2, int numbersize2, int *union_size);




void NumSort(int *number, int numbersize) {
    int min, temp;
    int i;
    int j;
    for (i = 0; i<numbersize - 1; i++) {
        min = i;
        for (j = i + 1; j<numbersize; j++) {
            if (number[min]>number[j]) {
                min = j;
            }
        }
        if (min != i) {
            temp = number[min];
            number[min] = number[i];
            number[i] = temp;
        }
    }
}



int *intersection_numbers(int *number1, int numbersize1, int *number2, int numbersize2,int *intersection_size) {
    int temp, i, j;
    int *result = (int *)malloc(numbersize1 * sizeof(int));


    *intersection_size =  0;
    NumSort(number1, numbersize1);
    NumSort(number2, numbersize2);


    temp = number1[numbersize1 - 1] + number2[numbersize2 - 1];
        for (i = 0, j = 0; i<numbersize1&&j<numbersize2;) {
            if (number1[i]>number2[j]) {
                j++;
            }
            else if (number1[i]<number2[j]) {
                i++;
            }
            else {
                if (temp != number1[i]) {
                    result[(*intersection_size)++] = number1[i];
                    temp = number1[i];
                }
                i++;
                j++;


            }
        }
    return result;
}


int* union_numbers(int* number1, int numbersize1, int* number2, int numbersize2,int *union_size) {


    int temp, i, j;
    int *result = (int *)malloc((numbersize2 + numbersize1) * sizeof(int));



    NumSort(number1, numbersize1);
    NumSort(number2, numbersize2);
    i = 0;
    j = 0;


    *union_size = 0;
    temp = number1[numbersize1 - 1] + number2[numbersize2 - 1];
        for (i = 0, j = 0; i<numbersize1 || j<numbersize2;) {
            if (j != numbersize2 && number1[i]>number2[j]) {
                result[(*union_size)++] = number2[j];
                j++;
            }
            else if (i != numbersize1 && number1[i]<number2[j]) {
                result[(*union_size)++] = number1[i];
                i++;
            }
            else if (j == numbersize2 && number1[i]>number2[j]) {
                result[(*union_size)++] = number1[i];
                i++;
            }
            else if (i == numbersize1 && number1[i]<number2[j]) {
                result[(*union_size)++] = number2[j];
                j++;


            }
            else {
                if (temp != number1[i]) {
                    result[(*union_size)++] = number1[i];
                    temp = number1[i];
                }
                i++;
                j++;


            }
        }
    return result;
}



int main(int argc, char *argv[])
{
    int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int i;
    int b[10] = { 2,4,6,8,10,12,14,16,18,20 };
    int intersection_size = 0  ;
    int union_size = 0 ;
    int *p = intersection_numbers(&a[0], 10, &b[0], 10,&intersection_size);


    printf("\n +++++ array a :\n");
    for (i = 0; i<10; i++) {
        printf(" %d\n", a[i]);
    }


    printf("\n +++++ array b :\n");
    for (i = 0; i<10; i++) {
        printf(" %d\n", b[i]);
    }


    printf("++++++ intersection of the array a && b\n");
    for (i = 0; i<intersection_size;) {
        printf(" %d\n", p[i]);
        i++;
    }


    int *p1 = union_numbers(&a[0], 10, &b[0], 10, &union_size);
    printf("++++++ union of the array a || b\n");
    for (i = 0; i<union_size;) {
        printf(" %d\n", p1[i]);
        i++;
    }


    getchar();
}

猜你喜欢

转载自blog.csdn.net/bleauchat/article/details/91397848