题解 | #非整数倍数据位宽转换24to128#
非整数倍数据位宽转换24to128
http://www.nowcoder.com/practice/6312169e30a645bba5d832c7313c64cc
用144bit位移寄存器实现,整理清楚循环,每三次一个循环,第一次移位6次(全部更新),第二次移位5次(留一个旧的,下次需要低2byte),第三次移位5次(留一个旧的,下次需要低1byte),然后循环。
`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
);
//parameter
parameter N = 6;
parameter BYTE_N = 3;
//defination
reg [143 : 0] SR;
reg [2 : 0] cnt;
wire add_cnt;
wire end_cnt;
reg [1 : 0] cnt_byte;
wire add_cnt_byte;
wire end_cnt_byte;
//output
always@(posedge clk or negedge rst_n)begin
if(!rst_n) SR <= 'd0;
else if(add_cnt) SR <= {SR[119 : 0], data_in};
end
assign add_cnt = valid_in;
assign end_cnt = (add_cnt && (cnt == N - 1) && (cnt_byte == 0)) | (add_cnt && (cnt == N - 2) && (cnt_byte != 0));
always@(posedge clk or negedge rst_n)begin
if(!rst_n) cnt <= 'd0;
else if(end_cnt) cnt <= 'd0;
else if(add_cnt) cnt <= cnt + 1'b1;
end
assign add_cnt_byte = end_cnt;
assign end_cnt_byte = add_cnt_byte && (cnt_byte == BYTE_N - 1);
always@(posedge clk or negedge rst_n)begin
if(!rst_n) cnt_byte <= 'd0;
else if(end_cnt_byte) cnt_byte <= 'd0;
else if(add_cnt_byte) cnt_byte <= cnt_byte + 1'b1;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) data_out <= 'd0;
else if(end_cnt)
case (cnt_byte)
2'b00 : data_out <= {SR[119 : 0], data_in[7 : 0]};
2'b01 : data_out <= {SR[111 : 0], data_in[15 : 0]};
2'b10 : data_out <= {SR[103 : 0], data_in[23 : 0]};
default :;
endcase
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) valid_out <= 'd0;
else if(end_cnt) valid_out <= 1'b1;
else valid_out <= 1'b0;
end
endmodule