联发科 笔试编程题

题目如下所示:

用Verilog代码开发一个模块。

在start信号后的做多2048个周期,输入总数是32768比特的数据,每个周期的输入的有效比特在0-32 之间,设计一个逻辑,将数据真利成32bit对齐输出。在结束输出Done信号,如果有任何异常,整理并输出异常信号。

输入信号

start:一个周期脉冲,表示任务开始

Data_in[31:0]

输出信号

Done

Data_out[31:0]

Error[X:0]

代码如下所示

module lfk_exam(
        input           clk,
        input           rst_n,
        input           start,
        input   [31:0]  data_in,
        input   [31:0]  data_in_valid,
        output        error,
        output                 done,
        output  reg[31:0]  data_out);
        reg [5:0]   cnt;
        integer i;
        reg [63:0]  data_reg_64;
        reg     ptr_flag;
        reg [5:0]   cnt_d1;
        reg [5:0]   cnt_d2;
        reg [63:0]  data_reg_d1;
        reg read_flag;
        reg [31:0]  read_out;
        reg [10:0]  count;
        reg [10:0]  count_d1;
        reg [31:0]  data_in_d1;
        reg [31:0]  data_in_valid_d1;
        reg [6:0]   count_read_flag;
        reg         reg_flag;//用来标记允许计数的时间
//2048 的计数器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
    count   <=  11'b111_1111_1111;
    reg_flag    <=1'b0;
    end
else if(start)begin
    count   <=  count+1'b1;
    reg_flag <=1'b1;  
    end
else    if(count!==11'b111_1111_1111)begin
    count <= count +1'b1;
    reg_flag <= 1'b1;
    end
else    begin
    count   <=  11'b111_1111_1111;
   reg_flag <=  1'b0;
    end    
end        
/****** *****出处的数据除开start都延迟一拍****************************************/
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
begin
    data_in_d1 <=32'b0;
    data_in_valid_d1    <=32'b0;
end
else begin
    data_in_d1 <=data_in;
    data_in_valid_d1    <=data_in_valid;
end
end      
 //计数有效的 的值个数
 always@(*)begin
 if(!rst_n)
 cnt=6'b0;
 else if(reg_flag==1'b1)begin
 for(i=0;i<32;i=i+1)begin
    if(data_in_valid_d1[i])begin
    data_reg_64[cnt]=data_in_d1[i];
    cnt=cnt+1'b1;
	end
 end
 end
 else begin
    cnt =  6'b0;
    data_reg_64=64'b0;
 end
 end

/******************时序逻辑,将当前的数据进行延迟输出*********************************/
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
    begin
        cnt_d1  <= 32'b0;
        cnt_d2  <= 32'b0;
        data_reg_d1<=64'b0;
    end
    else  begin
        cnt_d1  <= cnt;
        cnt_d2  <=cnt_d1;
        data_reg_d1<=data_reg_64;
    end
    end
/*************判断是否满足32位并进行输出,给出允许输出的信号***************/
always@(*)begin
if((cnt_d1>=32)&&(cnt_d2<32))begin
    ptr_flag=1'b0;
    read_flag=1'b1;//允许读出数据
end
else  if((cnt_d1>=32)&&(cnt_d2>=32))begin
    ptr_flag=1'b1;
    read_flag=1'b0;//不允许读出数据
    end
else if((cnt_d1<32)&&(cnt_d2>=32))begin
     ptr_flag=1'b1;  
     read_flag=1'b1;//允许读出数据 
end
else begin
     ptr_flag=1'b0;  
     read_flag=1'b0;//不允许读出数据 
end
end
/*******根据ptr_flag和read_flag进行相应的结果选择输出**********************/
always@(*)begin
case({ptr_flag,read_flag})
2'b00:   begin
          read_out=32'bz;  
         end
2'b01:   begin
          read_out=data_reg_d1[31:0];         
         end        
2'b10:   begin
          read_out=32'bz;         
         end
2'b11:   begin
          read_out=data_reg_d1[63:32];         
         end
endcase
end
/*********判断在2048个周期的时候是否输出了124个32bit数据***********/
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
    count_read_flag <= 7'b0;
    else if(read_flag)
    count_read_flag <=count_read_flag+1'b1;
    else
    count_read_flag <=count_read_flag;
end
/*******判断是否出现异常情况*******/
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
    count_d1<=11'b0;
    else
    count_d1<=count;
    end
assign done=((count_d1<=11'd2047)&&(count_read_flag>=7'd124))?1'b1:1'b0;
assign  error=((count_d1==11'd2047)&&(count_read_flag<7'd124))?1'b1:1'b0;
/******结果的输出*******/
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
    data_out <=32'b0;
    else
    data_out <=  read_out;
    end
endmodule

仿真波形

经过仿真验证,代码实现了题目中所要求的结果。

 

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页