题解 | #非整数倍数据位宽转换24to128#
非整数倍数据位宽转换24to128
https://www.nowcoder.com/practice/6312169e30a645bba5d832c7313c64cc
`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
);
localparam INIT = 2'd0;
localparam GET3_1 = 2'd1;
localparam GET2_2 = 2'd2;
localparam GET1_3 = 2'd3;
reg [1:0] STATE_CURR, STATE_NEXT;
always@(posedge clk or negedge rst_n)begin
if(~rst_n)
STATE_CURR <= INIT;
else
STATE_CURR <= STATE_NEXT;
end
reg [2:0] cnt5;
always@(posedge clk or negedge rst_n)begin
if(~rst_n)
cnt5 <= 3'd0;
else if(valid_in)
if(STATE_NEXT == INIT && cnt5 == 3'd5)
cnt5 <= 3'd0;
else
cnt5 <= (cnt5 == 3'd5) ? 3'd1 : cnt5 + 1'b1;
else
cnt5 <= cnt5;
end
always@(*)begin
if(~rst_n)
STATE_NEXT <= INIT;
else if(valid_in)
if(STATE_CURR == INIT)
STATE_NEXT <= GET3_1;
else if(cnt5 == 3'd5)
case(STATE_CURR)
GET3_1 : STATE_NEXT <= GET2_2;
GET2_2 : STATE_NEXT <= GET1_3;
GET1_3 : STATE_NEXT <= INIT;
default : STATE_NEXT <= INIT;
endcase
else
STATE_NEXT <= STATE_CURR;
end
reg [119:0] data_buffer;
always@(posedge clk or negedge rst_n)begin
if(~rst_n)
data_buffer <= 120'd0;
else if(valid_in)
data_buffer <= {data_buffer[95:0],data_in};
else
data_buffer <= data_buffer;
end
always@(posedge clk or negedge rst_n)begin
if(~rst_n)begin
valid_out <= 1'b0;
data_out <= 128'd0;
end
else if(cnt5 == 3'd5)begin
valid_out <= 1'b1;
case(STATE_CURR)
GET3_1 : data_out <= {data_buffer[0+:120],data_in[23-: 8]};
GET2_2 : data_out <= {data_buffer[0+:112],data_in[23-:16]};
GET1_3 : data_out <= {data_buffer[0+:104],data_in[23-:24]};
default : data_out <= data_out;
endcase
end
else begin
valid_out <= 1'b0;
data_out <= data_out;
end
end
endmodule
思路: