非整数倍数据位宽转换8to12
所谓非整数倍,就是利用一个cnt去周期性决定寄存器里怎么输出,这个cnt的值,是最小公倍数
寄存器就正常的寄存,怎么输入怎么寄存
`timescale 1ns/1ns
module width_8to12(
input clk ,
input rst_n ,
input valid_in ,
input [7:0] data_in ,
output reg valid_out,
output reg [11:0] data_out
);
reg[7:0]data_lock;
reg[1:0]valid_cnt;
always@(posedge clk,negedge rst_n)begin
if(!rst_n)
data_lock<=0;
else if(valid_in)
data_lock<=data_in;
end
always@(posedge clk,negedge rst_n)begin
if(!rst_n)
valid_cnt<=0;
else if(valid_in)begin
if(valid_cnt==2'd2)
valid_cnt<=0;
else
valid_cnt<=valid_cnt+1;
end
end
always@(posedge clk,negedge rst_n)begin
if(!rst_n)
valid_out<=0;
else if(valid_in&&valid_cnt==1)
valid_out<=1;
else if(valid_in&&valid_cnt==2)
valid_out<=1;
else
valid_out<=0;
end
always@(posedge clk,negedge rst_n)begin
if(!rst_n)
data_out<=0;
else if(valid_in&&valid_cnt==1)
data_out<={data_lock,data_in[7:4]};
else if(valid_in&&valid_cnt==2)
data_out<={data_lock[3:0],data_in};
end
endmodule
为什么不需要2个8bit的寄存器进行数据缓存:
根据时序图, data_out是在两个数据输入之后的下一个时钟周期产生输出,如果采用两个寄存器缓存两个数据,那么第二个数据还没缓存进寄存器后就要输出数据,这样不能实现满足时序要求的数据输出。
根据时序图,数据是在第二个数据到来之后输出,当仅有一个数据到来时,不产生输出,所以内部设计一个计数器(valid_cnt),用来指示数据接收状态。当检测到valid_in拉高时,valid_cnt加1,valid_cnt在0-2之间循环,valid_cnt复位值是0。当valid_cnt是1或2,且valid_in为高时,输出数据,valid_out拉高。
当valid_cnt==1且valid_in为高时,data_out <= {data_lock, data_in[7:4]};当valid_cnt==2且valid_in为高时,data_out <= {data_lock[3:0], data_in}。
就是说,复位的时候,寄存器里一个也没有,所以就不能输出,然后存了一个后,就是1,再来就可以输出,这时输出,就输出存的8个以及新输入的前4个,并且进到2,表示此时寄存器里存的是第二个输入的,而且前半个已经输出过了,该输出后四个,所以此时要输出,就是输出寄存器的后四个以及新输入的全部,这时候寄存器内部实际上也就相当于空了
也就是说valid_cnt决定输出信号,怎么处理寄存器里的信号
电路图
就是时序逻辑就是要用触发器,<=最直接的就是D触发器
整数倍数据位宽转换8to16
`timescale 1ns/1ns
module width_8to16(
input clk ,
input rst_n ,
input valid_in ,
input [7:0] data_in ,
output reg valid_out,
output reg [15:0] data_out
);
reg[0:0]cnt;
reg[7:0]ram;
always@(posedge clk,negedge rst_n)begin
if(!rst_n)
cnt<=0;
else if(valid_in)
cnt<=(cnt)?0:1;
else
cnt<=cnt;
end
always@(posedge clk,negedge rst_n)begin
if(!rst_n)
ram<=0;
else if(valid_in)
ram<=data_in;
else
ram<=ram;
end
always@(posedge clk,negedge rst_n)begin
if(!rst_n)begin
da