数据降速增宽
1.要求
(1)对一路8bit信号进行1/2倍降速,并将8bit转换为16bit输出。
(2)输出信号有效位在完成一次8bit转16bit时拉高,其余时间拉低
(3)不使用FIFO IP核
2.意义:
(1)练习串并转换思想
(2)练习数据降速、拓转位宽
(3)练习简单跨时钟域问题处理
3.总结:
(1)串并转换思想用移位方法实现;
(2)移位方法使用数据拼接更好
(3)数据间因为打拍会有延迟,要调理一下时序
(4)保持16bit数据维持两个时钟周期的方法是将需要输出的16bit数据打一拍,在dbyte_valid高时data_out为原16bit数据,低时data_out为打一拍后的16bit数据。
Verilog Code
// *********************************************************************************
// Project Name : Byte2dbyte
// Email : 277808516@qq.com
// Create Time : 2020/8/22
// File Name : byte2dbyte.v
// Module Name : byte2dbyte
// Abstract : Yang Cheng Yu
// editor : Notepad++
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// 2020/8/22 杨成煜 1.0 Original
//
// *********************************************************************************
//`timescale 1ns/1ns
//==================defines=====================
`define SIM
`define V1
module byte2dbyte(
//================System Signal================
input clk,
input rst_n,
//================Interface====================
input [7:0] data_in,
output [15:0] data_out,
output data_valid
);
//================parameters===================
`ifndef SIM
`else
`endif
//================System regs==================
reg [15:0] data_dbyte;
reg [15:0] data_dbyte_d1;
reg data_out_valid;
reg [7:0] data_in_reg;
reg data_in_valid;
assign data_out = data_out_valid?data_dbyte:data_dbyte_d1;
assign data_valid = data_in_valid&data_out_valid;
// data_in_valid
always @(posedge clk)begin
if(!rst_n)
data_in_valid <= 1'b0;
else
data_in_valid <= 1'b1;
end
//data_in 打一拍
always @(posedge clk)begin
if(!rst_n)
data_in_reg <= 8'd0;
else
data_in_reg <= data_in;
end
//data_dbyte 串并转换
always @(posedge clk)begin
if(!rst_n)
data_dbyte <= 16'd0;
else
data_dbyte <= {data_dbyte[7:0],data_in_reg};
end
//data_dbyte_d1
always @(posedge clk)begin
if(!rst_n)
data_dbyte_d1 <= 16'd0;
else
data_dbyte_d1 <= data_dbyte;
end
//data_out_valid
always @(posedge clk)begin
if(!rst_n)
data_out_valid <= 1'b1;
else
data_out_valid <= ~data_out_valid;
end
//================Main Codes===================
endmodule
TestBench Code
// *********************************************************************************
// Project Name : tb_byte2dbyte
// Email : 277808516@qq.com
// Create Time : 2020/8/21
// File Name : tb_byte2dbyte.v
// Module Name : tb_byte2dbyte
// Abstract : Yang Cheng Yu
// editor : Notepad++
// *********************************************************************************
// Modification History:
// Date By Version Change Description
// -----------------------------------------------------------------------
// 2020/3/ 杨成煜 1.0 Original
//
// *********************************************************************************
`timescale 1ns/1ns //时间精度
`define clock_period 20 //时钟周期
module tb_byte2dbyte; //实体名称
//=====================<系统端口>=============================
reg clk;
reg rst_n;
//=====================<外设端口>=============================
reg [7:0] data_in;
wire [15:0] data_out;
wire data_valid;
integer i;
byte2dbyte byte2dbyte_inst(
//================System Signal================
.clk (clk),
.rst_n (rst_n),
//================Interface====================
.data_in (data_in),
.data_out (data_out),
.data_valid (data_valid)
);
//=====================<时钟信号>=============================
initial begin
clk = 1;
forever
#(`clock_period/2) clk = ~clk;
end
//=====================<复位信号>=============================
initial begin
rst_n = 0;#(`clock_period*20+1);
rst_n = 1;
end
//=====================<激励信号>=============================
initial begin
data_in = 0;
#(`clock_period*20+1);//初始化
for(i=0;i<255;i=i+1)begin
data_in = i;
#(`clock_period);
end
end
endmodule