1、veilog进阶篇 VL32 非整数倍数据位宽转换24to48
描述:
实现数据位宽转换电路,实现24bit数据输入转换为128bit数据输出。其中,先到的数据应置于输出的高bit位。
valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号。 观察时序图:1、valid_out和data_out是在已存入5个数据且第6个数据到来后产生输出,且每个输入的数据中,低位数据会优先输出,图中第6个输入数据中的高8bit数据f2优先输出;
2、当数据缓存不满足128bit时,不会产生输出valid_out和data_out。
分析:
1、要实现24bit数据至128bit数据的位宽转换,必须要用寄存器将先到达的数据进行缓存。
2、24bit数据至128bit数据,相当于5个输入数据+第6个输入数据的拼接成一个输出数据,出于对资源的节省以及时序要求,采用120bit的寄存器进行数据缓存。
3、根据时序推演,数据是在第6个、第11个、第16个数据到来之后输出,所以内部设计一个计数器,用来指示数据接收状态。(24*16=128*3)
a、当检测到valid_in拉高时,valid_cnt加1,valid_cnt在0-15之间循环,valid_cnt复位值是0。
b、当valid_cnt是5或10或15,且valid_in为高时,输出数据,valid_out拉高。
![](/i/l/?n=23&i=blog/1946646/202307/1946646-20230731171656590-1071053177.png)
`timescale 1ns/1ns module width_24to128( input clk , input rst_n , input valid_in , input [23:0] data_in , output reg valid_out , output reg [127:0] data_out ); reg [119:0] data_reg; reg [4:0] cnt; always @(posedge clk or negedge rst_n) begin if(~rst_n) cnt <= 5'd0; else if(valid_in) cnt <= (cnt==5'd15)? 5'd0 : cnt+1'b1; end always @(posedge clk or negedge rst_n) begin if(~rst_n) begin data_reg <= 120'd0; data_out <= 128'd0; end else if(valid_in) begin if(cnt==5'd5) begin data_reg <= {data_reg[119:16],data_in[15:0]}; data_out <= {data_reg,data_in[23:16]}; end else if(cnt==5'd10) begin data_reg <= {data_reg[119:8],data_in[7:0]}; data_out <= {data_reg[111:0],data_in[23:8]}; end else if(cnt==5'd15) begin data_reg <= {data_reg[119:24],data_in}; data_out <= {data_reg[103:0],data_in}; end else data_reg <= {data_reg[95:0],data_in}; end end always @(posedge clk or negedge rst_n) begin if(~rst_n) valid_out <= 1'b0; else if((cnt==5'd5 || cnt==5'd10 || cnt==5'd15) && valid_in) valid_out <= 1'b1; else valid_out <= 1'b0; end endmodule
2、veilog进阶篇 VL33 非整数倍数据位宽转换8to12
描述:实现数据位宽转换电路,实现8bit数据输入转换为12bit数据输出。其中,先到的数据应置于输出的高bit位。
alid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号。 观察时序图:1、valid_out和data_out是在两个数据输入之后的下一个时钟周期产生输出;
2、当仅有一个数据输入后,不会产生输出valid_out和data_out,而是会等待下一个数据到来之后完成两个数据的拼接,才产生输出valid_out和data_out。
分析: 1、要实现8bit数据至12bit数据的位宽转换,必须要用寄存器将先到达的数据进行缓存。8bit数据至12bit数据,相当于1.5个输入数据拼接成一个输出数据,出于对资源的节省以及时序要求,采用1个8bit的寄存器(data_lock)进行数据缓存。 2、根据时序图,数据是在第二个数据到来之后输出,当仅有一个数据到来时,不产生输出,所以内部设计一个计数器(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}。![](/i/l/?n=23&i=blog/1946646/202307/1946646-20230731174827184-1078367324.png)
`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 [1:0] cnt; reg [7:0] data_lock; always @(posedge clk or negedge rst_n) begin if(~rst_n) cnt <= 'b0; else if(valid_in) cnt <= (cnt==2'b10) ? 'b0 : cnt+1'b1; end always @(posedge clk or negedge rst_n) begin if(~rst_n) data_lock <= 'b0; else if(valid_in) data_lock <= data_in; end always @(posedge clk or negedge rst_n) begin if(~rst_n) begin data_out <= 'b0; valid_out <= 'b0; end else if(valid_in && cnt==2'b01) begin data_out <= {data_lock,data_in[7:4]}; valid_out <= 1'b1; end else if(valid_in && cnt==2'b010) begin data_out <= {data_lock[3:0],data_in}; valid_out <= 1'b1; end else valid_out <= 1'b0; end endmodule
标签:输出,cnt,转换,data,整数,牛客,valid,数据,out From: https://www.cnblogs.com/blog-address/p/17594057.html