[牛客网刷题]L32 非整数倍数据位宽转换24to128

news/2025/2/22 21:33:22/

1.题目描述

实现数据位宽转换电路,实现24bit数据输入转换为128bit数据输出。其中,先到的数据应置于输出的高bit位。电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时钟信号;rst_n是异步复位信号。
在这里插入图片描述

2.波形图

在这里插入图片描述

3.错误分析

最开始的时候分析问题,只考虑了在一次数据传输的周期中的传输过程,由于是24to128的数据转换,需要传输六次,且最后一次的数据只会存最高的8位。即开始时的数据转换是通过data_out_reg缓存数据,但是最后一次会慢一拍,所以,最后需要通过data_out再缓存最终的高位数据。

reg [127:0] data_out_reg;always@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_out_reg <= 128'd0;else if(valid_in)data_out_reg <= {data_out_reg[103:0],data_in};elsedata_out_reg <= 128'd0;end
always@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_out <= 128'd0;else if(valid_in && (data_cnt == 4'd5))data_out <= {data_out_reg[119:0],data_in[23:16]};else data_out <= data_out;  end

4.错误代码

整体代码也不赘述了,只能实现次6位数据的转换,后续数据处理都是错误的:

`timescale 1ns/1nsmodule 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] data_cnt;always@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_cnt <= 4'd0;else if(valid_in == 1'b1)data_cnt <= (data_cnt == 4'd5)? 4'd0 : data_cnt + 1'b1;endalways@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)valid_out <= 1'b0;else if(data_cnt == 4'd5 && valid_in)valid_out <= 1'b1;elsevalid_out <= 1'b0;endreg [127:0] data_out_reg;always@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_out_reg <= 128'd0;else if(valid_in)data_out_reg <= {data_out_reg[103:0],data_in};elsedata_out_reg <= 128'd0;endalways@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_out <= 128'd0;else if(valid_in && (data_cnt == 4'd5))data_out <= {data_out_reg[119:0],data_in[23:16]};else data_out <= data_out;  endendmodule

验证代码,一次数据转换:

`timescale 1ns/1nsmodule width_24to128_tb;reg 			clk			;
reg 			rst_n		;
reg 			valid_in	;
reg  [23:0] 	data_in		;wire			valid_out	;
wire [127:0]	data_out	;width_24to128 inst1(.clk(clk),.rst_n(rst_n),.valid_in(valid_in),.data_in(data_in),.valid_out(valid_out),.data_out(data_out)
);initial begin clk = 1'b0; forever begin #10; clk = ~clk; end end
initial begin rst_n = 1'b0; #25; rst_n = 1'b1; end
initial begin valid_in = 1'b0; #52 ;valid_in = 1'b1; #120;valid_in =1'b0; end
initial begin data_in = 24'd0; #52 ;data_in = 24'ha0a1a2;#20;data_in = 24'hb2b1b0;#20;data_in = 24'hc2c1c0;#20;data_in = 24'hd2d1d0;#20;data_in = 24'he2e1e0;#20;data_in = 24'hf2f1f0;#20;end
initial begin #5000; $stop; endendmodule

在这里插入图片描述
从波形图也可以看出问题所在,所以对RTL代码进行修改。

5.正确分析

输入数据是24bit,输出数据是128bit,要找到二者的公倍数,才能将所有传输的数据都进行一个合理的整合。因为128 * 3 = 24 * 16,所以每输入16个有效数据,就可以产生三个完整的输出。因此设置一个仅在输入数据有效时工作的计数器cnt,计数范围是0-15。

`timescale 1ns/1nsmodule 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] data_cnt;//16位always@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_cnt <= 4'd0;else if(valid_in == 1'b1)data_cnt <=  data_cnt + 1'b1;endalways@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)valid_out <= 1'b0;else if((data_cnt == 4'd5 || data_cnt == 4'd10 || data_cnt == 4'd15) && valid_in)valid_out <= 1'b1;elsevalid_out <= 1'b0;endreg [127:0] data_out_reg;always@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_out_reg <= 128'd0;else if(valid_in)data_out_reg <= {data_out_reg[103:0],data_in};elsedata_out_reg <= data_out_reg;endalways@(posedge clk or negedge rst_n)beginif(rst_n == 1'b0)data_out <= 128'd0;else if(data_cnt == 4'd5)data_out <= {data_out_reg[119:0],data_in[23:16]};else if(data_cnt == 4'd10)data_out <= {data_out_reg[119:0],data_in[23:8]};else if(data_cnt == 4'd15)data_out <= {data_out_reg[119:0],data_in[23:0]};else data_out <= data_out;  endendmodule

后续的验证波形大家可以自己写一下,后面如果有,相对来说还是比较简单的。祝大家越学越开心。


http://www.ppmy.cn/news/363242.html

相关文章

GT20L16S1Y GT30L32S4W 横置竖排 转换为 横置横排

GT20L16S1Y GT30L32S4W 横置竖排 转换为 横置横排 参考&#xff1a;https://blog.csdn.net/lljss1980/article/details/126566150 GT20L16S1Y 为横置竖排 GT30L32S4W 为横置横排 暂时为了适配 写了一个适配16 * 16点阵 32 * 32点阵 横置竖排 转换为 横置横排 的算法 /// brie…

GT30L32S4W中文字库芯片+墨水屏显示调好程序分享

这公司叫高通&#xff0c;但新版规格书不带地址运算&#xff0c;带地址运算规格书下载GT30L32S4W规格书&#xff0c;带地址运算 芯片管脚配置&#xff1a; 基础驱动及读取代码&#xff1a; /********************************************************************* brief …

IA32-Linux地址转换过程

在保护模式下&#xff0c;IA32采用段页式虚拟内存管理&#xff0c;即先分段再分页。地址的类型有以下三种&#xff1a; 逻辑地址&#xff08;48bit&#xff09;线性地址&#xff08;32bit&#xff09;物理地址 由逻辑地址转化为线性地址由分段过程完成&#xff0c;由线性地址…

[Android Pro] Android P版本 新功能介绍和兼容性处理(三)Android Studio 3.0 ~ 3.2 其他特性...

cp : https://blog.csdn.net/yi_master/article/details/80067198 1&#xff1a;JAVA8特性支持 1&#xff09;Base64.java 在升级到as3.0之后&#xff0c;我们便可以使用Base64.java这个类了&#xff0c;这个类的在java.util.Base64包下&#xff1b;而android里面也有一个Bas…

MODBUS转EtherNet/IP网关连接罗克韦尔(AB)PLC与英威腾变频器配置案例

小疆智控GW-EIP-001网关&#xff0c;用于将多个MODBUS从站设备接入ETHERNET/IP主站网络&#xff0c;实现MODBUS转ETHERNET/IP功能。配上MODBUS转EtherNet网关专用的EDS文件,实现ETHERNET/IP主站对MODBUS从站设备的控制。 硬件配置&#xff1a;罗克韦尔&#xff08;AB&#xff0…

【杂项】Substance Designer学习笔记

界面元素 数字键切换图表中显示的接口详细程度 primary input 主输入口- 节点左侧输入口中多了个灰色圆心的输入口&#xff0c;它的输入值决定了该节点的默认属性 color depth - 该节点输出的色彩精度。位于各个节点右下角的字母数字结合&#xff0c;首字母C代表色彩四通道&a…

FusionF1 DSP结构知识

完美不是一个小细节;但注重细节可以成就完美。–米开朗基罗 专用DSP和通用处理器最大的差别在于&#xff0c;有很多特殊的计算处理来提高运算效率。在提高运算效率方便&#xff0c;从大的方面可以优化算法&#xff0c;而小的方面可以细微到通用寄存器的使用、变量类型的定义等。…

“高通”字库芯片的使用方法

STM32字库 “高通”字库芯片的使用方法 “高通”字库芯片的使用方法 STM32字库前言一、电路设计二、程序设计代码如下&#xff1a; 整体代码部分1.字库初始化2.字库头文件3.主函数 前言 本文应用了这位大神的指导链接&#xff1a;https://blog.csdn.net/qq_40102829/article/…