题目如下所示:
用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
仿真波形
经过仿真验证,代码实现了题目中所要求的结果。