题解 | #非整数倍数据位宽转换24to128#

非整数倍数据位宽转换24to128

https://www.nowcoder.com/practice/6312169e30a645bba5d832c7313c64cc

    //本题需要注意的就是128并不能整除24,所以一次并不是完整的整数个,经过计算分析,可以得知三次输出刚好是整数个24bit,总共需要16次
    //这个就可以选择采用状态机,当然也可以直接对计数器进行输出,采用状态机就是三个状态,三个都有不同的输出,对应的时刻分别是5,10和15
    //此题重点是理解需要多少次才能完整的输出数据而不需要下一个数据来借位

`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
);
    
    //本题需要注意的就是128并不能整除24,所以一次并不是完整的整数个,经过计算分析,可以得知三次输出刚好是整数个24bit,总共需要16次
    //这个就可以选择采用状态机,当然也可以直接对计数器进行输出,采用状态机就是三个状态,三个都有不同的输出,对应的时刻分别是5,10和15
    //此题重点是理解需要多少次才能完整的输出数据而不需要下一个数据来借位
    
    localparam    One_st  = 2'b01;
    localparam    Two_st  = 2'b10;
    localparam    Thre_st = 2'b11;
    
    reg    [1:0]    cur_state;
    reg    [1:0]    nex_state;
    
    reg    skip_en;
    
    
    reg    [3:0]      data_in_cnt;
    reg    [127:0]    data_out_temp;
    
    
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)  
            data_in_cnt <= 4'd0;
        else
            begin
                if(valid_in)
                    begin
                        if(data_in_cnt == 4'd15)
                            data_in_cnt <= 4'b0;
                        else
                            data_in_cnt <= data_in_cnt + 1'b1;
                    end
                else
                    data_in_cnt <= data_in_cnt;
            end
    end
    
    
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            cur_state <= One_st;
        else
            cur_state <= nex_state;
    end
    
    always@(*)
    begin
        nex_state = One_st;
        case(cur_state)
            One_st        :    begin
                    if(skip_en)
                        nex_state = Two_st;
                    else
                        nex_state = One_st;
                end
            Two_st        :    begin
                    if(skip_en)
                        nex_state = Thre_st;
                    else
                        nex_state = Two_st;
                end
            Thre_st       :    begin
                    if(skip_en)
                        nex_state = One_st;
                    else
                        nex_state = Thre_st;
                end
            default       :    nex_state = One_st;
        endcase
    end
    
    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            begin
                data_out <= 128'b0;
                valid_out <= 1'b0;
                skip_en <= 1'b0;
            end
        else
            begin
                skip_en <= 1'b0;
                case(nex_state)
                    One_st    :    begin
                            if(data_in_cnt == 4'd5)
                                begin
                                    skip_en <= 1'b1;
                                    data_out <= {data_out_temp[119:0] , data_in[23:16]};
                                    valid_out <= 1'b1;
                                end
                            else
                                begin
                                    skip_en <= 1'b0;
                                    data_out <= data_out;
                                    valid_out <= 1'b0;
                                end
                        end
                    Two_st    :    begin
                            if(data_in_cnt == 4'd10)
                                begin
                                    skip_en <= 1'b1;
                                    data_out <= {data_out_temp[111:0] , data_in[23:8]};
                                    valid_out <= 1'b1;
                                end
                            else
                                begin
                                    skip_en <= 1'b0;
                                    data_out <= data_out;
                                    valid_out <= 1'b0;
                                end
                        end
                    Thre_st   :    begin
                            if(data_in_cnt == 4'd15)
                                begin
                                    skip_en <= 1'b1;
                                    data_out <= {data_out_temp[103:0] , data_in};
                                    valid_out <= 1'b1;
                                end
                            else
                                begin
                                    skip_en <= 1'b0;
                                    data_out <= data_out;
                                    valid_out <= 1'b0;
                                end
                        end
                    default   :    ;
                endcase
            end
    end
    

    always@(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            data_out_temp <= 128'b0;
        else
            if(valid_in)
                data_out_temp <= {data_out_temp[103:0] , data_in};
            else
                data_out_temp <= data_out_temp;
    end
    
    
endmodule

全部评论

相关推荐

不愿透露姓名的神秘牛友
05-01 13:13
ecece:这么明目张胆虚报就业率啊
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务