解题方法:先分析倍数关系,确定需要几次转换,且先到的数据要置于输出的高位,再把每次未传输完的数据锁存起来,在下一个时钟周期继续进行传输,且剩下的数据也要置于高位,然后继续补充输入。此时数据输出有效。
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 cnt;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)
- cnt <= 1'b0;
- else begin
- if(valid_in)begin
- cnt <= cnt + 1'b1;
- end
- end
- end
- reg [7:0] data_reg;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- data_out <= 16'b0;
- valid_out <= 1'b0;
- end
- else begin
- if(valid_in)begin
- if(cnt == 1'b0)begin
- data_reg <= data_in;
- valid_out <= 1'b0;
- end
- else begin
- data_out <= {data_reg,data_in};//先到的数据置于输出数据的高位,后到的置于低位
- valid_out <= 1'b1;
- end
- end
- else begin
- valid_out <= 1'b0;
- end
- end
- end
- endmodule
8to12 注释非常好,易于理解
- `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;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)
- cnt <= 2'b0;
- else if(valid_in)begin
- if(cnt == 2'd2)
- cnt <= 2'd0;
- else
- cnt <= cnt + 2'd1;
- end
- end
- reg [7:0] data_reg;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- data_out <= 12'd0;
- valid_out <= 1'b0;
- data_reg <= 8'b0;
- end
- else begin
- if(valid_in)begin
- case(cnt)
- 2'd0:begin
- data_reg <= data_in; //先高8位
- valid_out <= 1'd0;
- end
- 2'd1:begin
- data_out <= {data_out[7:0],data_in[7:4]}; //后低四位
- data_reg[3:0] <= data_in[3:0]; //剩余data_in的低四位先暂存
- valid_out <= 1'b1;
- end
- 2'd2:begin
- data_out <= {data_reg[3:0],data_in[7:0]}; //暂存的四位放在高位,新添加8位输入
- valid_out <= 1'b1;
- end
- default:begin
- data_reg <= 8'b0;
- data_out <= 12'b0;
- valid_out <= 1'b0;
- end
- endcase
- end
- else begin
- valid_out <= 1'b0;
- end
- end
- end
- endmodule
非整数倍数数据位宽转换24to128 需要转换3次128*3=24*16
- `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 [3:0] cnt;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)
- cnt <= 4'd0;
- else if(valid_in==1'd1)
- cnt <= cnt + 4'd1;
- end
- reg [15:0] data_reg;
- reg [127:0] data_out_r;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n) begin
- data_out <= 128'b0;
- valid_out <= 1'b0;
- data_out_r <= 128'b0;
- end
- else begin
- if(valid_in)begin
- case(cnt)
- 4'd0:begin
- data_out_r[127:104] <= data_in;
- valid_out <= 1'b0;
- end
- 4'd1:begin
- data_out_r[103:80] <= data_in;
- valid_out <= 1'b0;
- end
- 4'd2:begin
- data_out_r[79:56] <= data_in;
- valid_out <= 1'b0;
- end
- 4'd3:begin
- data_out_r[55:32] <= data_in;
- valid_out <= 1'b0;
- end
- 4'd4:begin
- data_out_r[31:8] <= data_in;
- valid_out <= 1'b0;
- end
- 4'd5:begin //剩余8位,将输入的高8位置于输出的低位
- data_out <= {data_out_r[127:8],data_in[23:16]};
- data_out_r[127:112] <= data_in[15:0];//将剩余输入的低16位锁存到输出锁存器中
- valid_out <= 1'b1;
- end
- 4'd6:begin
- data_out_r[111:88] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd7:begin
- data_out_r[87:64] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd8:begin
- data_out_r[63:40] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd9:begin
- data_out_r[39:16] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd10:begin //剩余16位,将输入的高16位置于输出的低位
- data_out <= {data_out_r[127:16],data_in[23:8]};
- data_out_r[127:120] <= data_in[7:0];//将剩余输入的低8位锁存到输出锁存器中
- valid_out <= 1'b1;
- end
- 4'd11:begin
- data_out_r[119:96] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd12:begin
- data_out_r[95:72] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd13:begin
- data_out_r[71:48] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd14:begin
- data_out_r[47:24] <= data_in[23:0];
- valid_out <= 1'b0;
- end
- 4'd15:begin//无剩余位,将新的输入的24位完整赋值到输出
- data_out_r[23:0] <= data_in[23:0];
- data_out <= {data_out_r[127:24],data_in[23:0]};
- valid_out <= 1'b1;
- end
- endcase
- end
- else begin
- valid_out <= 1'b0;
- end
- end
- end
- endmodule