verilog实现十进制正数与ASCII码互转
verilog实现十进制正数与ASCII码互转
1.小位宽数实现转ASCII码
1.小整数十进制转BCD码(8421码)
| 十进制数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| 8421码 | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
2.BCD码(8421码)转ASCII码
| 8421码 | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
|---|---|---|---|---|---|---|---|---|---|---|
| ASCII码(BIN) | 110000 | 110001 | 110010 | 110011 | 110100 | 110101 | 110110 | 110111 | 111000 | 111001 |
| ASCII码(DEC) | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
| ASCII码(HEX) | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
2.大位宽正整数实现转ASCII码
1.整数数位分割(BCD码)
分离数位有多种方法,除法和比较法,除法理解简单,但是在verilog中占用资源严重,需要使用到除法IP核,以下采用比较法。
比较法分离数位:
假设一个数为num=123,使用A,B,C来代替百位,十位和个位。(以下为伪代码)
分离百位:
if(num >=900) A = 9; num = num - 900;
else if(num >=800) A = 8; num = num - 800;
else if(num >=700) A = 7; num = num - 700;
else if(num >=600) A = 6; num = num - 600;
else if(num >=500) A = 5; num = num - 500;
else if(num >=400) A = 4; num = num - 400;
else if(num >=300) A = 3; num = num - 300;
else if(num >=200) A = 2; num = num - 200;
else if(num >=100) A = 1; num = num - 100;
else A = 0; num = num ;
分离十位和个位:
if(num >=90) B = 9; C = num - 90;
else if(num >=80) B = 8; C = num - 80;
else if(num >=70) B = 7; C = num - 70;
else if(num >=60) B = 6; C = num - 60;
else if(num >=50) B = 5; C = num - 50;
else if(num >=40) B = 4; C = num - 40;
else if(num >=30) B = 3; C = num - 30;
else if(num >=20) B = 2; C = num - 20;
else if(num >=10) B = 1; C = num - 10;
else B = 0; C = 0 ;
2.verilog实现十进制正数转ASCII码
module dec_ascii16(
input clk ,
input rst ,
input valid ,
input [15:0] din ,//MAX = 65535
output rdy ,
output [39:0] dout
);
reg [$clog2(9999)-1:0] num0;
reg [$clog2(999)-1:0] num1;
reg [$clog2(99)-1:0] num2;
reg [4*4-1:0] dig0;
reg [3*4-1:0] dig1;
reg [2*4-1:0] dig2;
reg [1*4-1:0] dig3;
reg [1*4-1:0] dig4;
reg [3:0] valid_d;
always @(posedge clk)begin
if(rst)begin
valid_d <= 0;
end else begin
valid_d <= {valid_d,valid};
end
end
always @(posedge clk)begin
if(rst)begin
dig0 <= 0;
num0 <= 0;
end else begin
if(din >= 60000) begin dig0 <= {dig0,4'd6}; num0 <= din - 60000; end
else if(din >= 50000)begin dig0 <= {dig0,4'd5}; num0 <= din - 50000; end
else if(din >= 40000)begin dig0 <= {dig0,4'd4}; num0 <= din - 40000; end
else if(din >= 30000)begin dig0 <= {dig0,4'd3}; num0 <= din - 30000; end
else if(din >= 20000)begin dig0 <= {dig0,4'd2}; num0 <= din - 20000; end
else if(din >= 10000)begin dig0 <= {dig0,4'd1}; num0 <= din - 10000; end
else begin dig0 <= {dig0,4'd0}; num0 <= din ; end
end
end
always @(posedge clk)begin
if(rst)begin
dig1 <= 0;
num1 <= 0;
end else begin
if (num0 >= 9000)begin dig1 <= {dig1,4'd9}; num1 <= num0 - 9000; end
else if(num0 >= 8000)begin dig1 <= {dig1,4'd8}; num1 <= num0 - 8000; end
else if(num0 >= 7000)begin dig1 <= {dig1,4'd7}; num1 <= num0 - 7000; end
else if(num0 >= 6000)begin dig1 <= {dig1,4'd6}; num1 <= num0 - 6000; end
else if(num0 >= 5000)begin dig1 <= {dig1,4'd5}; num1 <= num0 - 5000; end
else if(num0 >= 4000)begin dig1 <= {dig1,4'd4}; num1 <= num0 - 4000; end
else if(num0 >= 3000)begin dig1 <= {dig1,4'd3}; num1 <= num0 - 3000; end
else if(num0 >= 2000)begin dig1 <= {dig1,4'd2}; num1 <= num0 - 2000; end
else if(num0 >= 1000)begin dig1 <= {dig1,4'd1}; num1 <= num0 - 1000; end
else begin dig1 <= {dig1,4'd0}; num1 <= num0 ; end
end
end
always @(posedge clk)begin
if(rst)begin
dig2 <= 0;
num2 <= 0;
end else begin
if (num1 >= 900)begin dig2 <= {dig2,4'd9}; num2 <= num1 - 900; end
else if(num1 >= 800)begin dig2 <= {dig2,4'd8}; num2 <= num1 - 800; end
else if(num1 >= 700)begin dig2 <= {dig2,4'd7}; num2 <= num1 - 700; end
else if(num1 >= 600)begin dig2 <= {dig2,4'd6}; num2 <= num1 - 600; end
else if(num1 >= 500)begin dig2 <= {dig2,4'd5}; num2 <= num1 - 500; end
else if(num1 >= 400)begin dig2 <= {dig2,4'd4}; num2 <= num1 - 400; end
else if(num1 >= 300)begin dig2 <= {dig2,4'd3}; num2 <= num1 - 300; end
else if(num1 >= 200)begin dig2 <= {dig2,4'd2}; num2 <= num1 - 200; end
else if(num1 >= 100)begin dig2 <= {dig2,4'd1}; num2 <= num1 - 100; end
else begin dig2 <= {dig2,4'd0}; num2 <= num1 ; end
end
end
always @(posedge clk)begin
if(rst)begin
dig3 <= 0;
dig4 <= 0;
end else begin
if (num2 >= 90)begin dig3 <= {dig3,4'd9}; dig4 <= num2 - 90; end
else if(num2 >= 80)begin dig3 <= {dig3,4'd8}; dig4 <= num2 - 80; end
else if(num2 >= 70)begin dig3 <= {dig3,4'd7}; dig4 <= num2 - 70; end
else if(num2 >= 60)begin dig3 <= {dig3,4'd6}; dig4 <= num2 - 60; end
else if(num2 >= 50)begin dig3 <= {dig3,4'd5}; dig4 <= num2 - 50; end
else if(num2 >= 40)begin dig3 <= {dig3,4'd4}; dig4 <= num2 - 40; end
else if(num2 >= 30)begin dig3 <= {dig3,4'd3}; dig4 <= num2 - 30; end
else if(num2 >= 20)begin dig3 <= {dig3,4'd2}; dig4 <= num2 - 20; end
else if(num2 >= 10)begin dig3 <= {dig3,4'd1}; dig4 <= num2 - 10; end
else begin dig3 <= {dig3,4'd0}; dig4 <= num2 ; end
end
end
assign dout = {4'h3,dig0[4*4-1 -:4],4'h3,dig1[3*4-1 -:4],4'h3,dig2[2*4-1 -:4],4'h3,dig3[1*4-1 -:4],4'h3,dig4[1*4-1 -:4]};
assign rdy = valid_d[3];
endmodule
3.大位宽ASCII码转正整数
1.BCD码转整数
使用A,B,C来代替百位,十位和个位。(以下为伪代码)
num = A*100 + B*10 + C
dec(100) = bin(1100100) = 2^6 + 2^5 + 2^2
dec(10) = bin(1010) = 2^3 + 2^1
num =A*(2^6 + 2^5 + 2^2) + B*(2^3 + 2^1) + C
2.verilog实现ASCII码转十进制正数
module ascii_dec16(
input clk ,
input rst ,
input valid ,
input [39:0] din ,//MAX = 65535
output rdy ,
output reg [15:0] dout
);
reg [$clog2(60000)-1:0] num0;
reg [$clog2(9000)-1:0] num1;
reg [$clog2(900)-1:0] num2;
reg [$clog2(90)-1:0] num3;
reg [$clog2(9)-1:0] num4;
reg [$clog2(65535)-1:0] num5;
reg [$clog2(65535)-1:0] num6;
reg [2:0] valid_d;
always @(posedge clk)begin
if(rst)begin
valid_d <= 0;
end else begin
valid_d <= {valid_d,valid};
end
end
//10 = 1010 = 2^3 + 2^1
//100 = 1100100 = 2^6 + 2^5 + 2^2
//1000 = 001111101000 = 2^10 - 2^5 + 2^3
//10000 = 0010011100010000 = 2^13 + 2^11 - 2^8 + 2^4
always @(posedge clk)begin
if(rst)begin
num0 <= 0;
end else begin
num0 <= {din[39-4 -:4],13'd0} + {din[39-4 -:4],11'd0} - {din[39-4 -:4],8'd0} + {din[39-4 -:4],4'd0};
end
end
always @(posedge clk)begin
if(rst)begin
num1 <= 0;
end else begin
num1 <= {din[39-12 -:4],10'd0} - {din[39-12 -:4],5'd0} + {din[39-12 -:4],3'd0};
end
end
always @(posedge clk)begin
if(rst)begin
num2 <= 0;
end else begin
num2 <= {din[39-20 -:4],6'd0} + {din[39-20 -:4],5'd0} + {din[39-20 -:4],2'd0};
end
end
always @(posedge clk)begin
if(rst)begin
num3 <= 0;
end else begin
num3 <= {din[39-28 -:4],3'd0} + {din[39-28 -:4],1'd0};
end
end
always @(posedge clk)begin
if(rst)begin
num4 <= 0;
end else begin
num4 <= din[39-36 -:4] ;
end
end
always @(posedge clk)begin
if(rst)begin
num5 <= 0;
end else begin
num5 <= num0 + num1 ;
end
end
always @(posedge clk)begin
if(rst)begin
num6 <= 0;
end else begin
num6 <= num2 + num3 + num4 ;
end
end
always @(posedge clk)begin
if(rst)begin
dout <= 0;
end else begin
dout <= num5 + num6 ;
end
end
assign rdy = valid_d[2];
endmodule
4.仿真
module tb_ascii();
reg clk;
reg rst;
initial begin
rst = 1;
#300
rst = 0;
end
initial begin
clk = 0;
forever begin
#5 clk = ~clk;
end
end
wire rdy ;
wire [39:0] dout ;//MAX = 65535
reg valid ;
reg [15:0] din ;//MAX = 65535
always @(posedge clk)begin
if(rst)begin
valid <= 0;
din <= 0;
end else begin
valid <= 1;
din <= din + 1;
end
end
dec_ascii16 dec_ascii16(
.clk (clk ),
.rst (rst ),
.valid (valid ),
.din (din ),//MAX = 65535
.rdy (rdy ),
.dout (dout )
);
ascii_dec16 ascii_dec16(
.clk (clk ),
.rst (rst ),
.valid (rdy ),
.din (dout ),//MAX = 65535
.rdy ( ),
.dout ( )
);
endmodule
verilog实现十进制正数与ASCII码互转的更多相关文章
- [PHP] chr和ord函数实现字符串和ASCII码互转
chr和ord函数是用来字符串和ASCII码互转的. ASCII码是计算机所能显示字符的编码,它的取值范围是0-255,其中包括标点.字母.数字.汉字等.在编程过程中,经常把指定的字符转化为ASCI ...
- 用php的chr和ord函数实现字符串和ASCII码互转
http://shenyongqang.blog.163.com/blog/static/22439113201002941856838/ chr和ord函数是用来字符串和ASCII码互转的. ASC ...
- 将一个字符与对应Ascii码互转
package nicetime.com.practies; /** * Java中将一个字符与对应Ascii码互转 1 byte = 8bit 可以表示 0-127 */public class G ...
- java 字符与ASCII码互转
字符转对应ASCII码 // 方法一:将char强制转换为byte char ch = 'A'; byte byteAscii = (byte) ch; System.out.println(byte ...
- js 字符与ASCII码互转
将字符转为ASCII码 var str = "A"; str.charCodeAt(); var str1 = 'a'; str1.charCodeAt(); 将ASCII码转为字 ...
- Java字符串跟ASCII码互转
1.由于项目中遇到,在服务器端起的jar包程序,给前台发消息后,前段收到的消息出现乱码情况,所以采取在后才发消息前先把消息字符串转成ASCII码再发往前台,前台采取在收到后台消息先把ASCII码转成字 ...
- BCD与ASCII码互转-C语言实现
/*BCD 与 ASCII码转换*/ /******************************************************************* 函数名: asc2bc ...
- js字符与ASCII码互转的方法
大写字母A-Z对应的ASCII码值是65-90 小写字母a-z对应的ASCII码值是97-122 将字母转为ascii码的方法: 将ascii码转为对应字母的方法:
- C语言 16进制与ascii码互转
/*把ASCII字符转换为16进制 */ uint8_t char_to_hex(const uint8_t *ch) { uint8_t value = 0; if(*ch >= 0 & ...
- 进制与ASCII码转换
LabeledEdit4.Text := chr(); // 用十进制方式赋值: ASCII码转换为字符 65 -> A LabeledEdit4.Text := #; // 用十进制方式赋值: ...
随机推荐
- TNN编译及使用
要使用 CMake 和 TNN 库基于 C++ 实现神经网络模型的推理预测,你需要按照以下步骤进行操作: 准备环境 确保已安装 CMake 和 C++ 编译器.并从 TNN 的 GitHub 仓库下载 ...
- Solution -「WC 2014」「洛谷 P3920」紫荆花之恋
\(\mathscr{Description}\) Link. 维护一棵树,初始时树空.接下来 \(n\) 次操作,每次操作加入一片叶子 \(u\),\(u\) 到其邻接点的边权为 \(w\) ...
- Java线程的创建和常见方法
1.线程,进程和管程 1.1线程(Thread) 定义:线程是操作系统中能够独立运行的最小单位,是进程的一个执行分支.一个进程可以包含多个线程,它们共享同一进程的资源(如内存和文件句柄). 特点: 线 ...
- PayDay Intermediate
nmap + dirsearch 发现web站点 扫目录 ┌──(root㉿kali)-[/home/ftpuserr] └─# nmap -p- -A 192.168.167.39 Starting ...
- 创新+1+1+1+1!筑牢算力底座,助推AI产业繁荣发展!
近日,ICT中国·2024高层论坛-云原生发展论坛在北京国家会议中心举办.天翼云出席<城市算力互联网实践指南>编制工作启动仪式.AI Cloud人工智能云服务标准体系阶段性成果发布仪式.算 ...
- Python if分支
分支语句: 1.单分支语句 1 if 条件表达式: 2 print("如果成立怎么养怎么样") 例:让用户输入年龄,如果大于18就可以去网吧偷耳机age = int(input(& ...
- mysql数据库表如何设计
单表数据量 所有表都需要添加注释,数据量建议控制在3000万以内 不保存大字段数据 不在数据库中存储图片.文件等大数据 表使用规范 拆分大字段和访问频率低的字段,分离冷热数据 单表字段数控制在 20 ...
- 百万架构师第四十三课:Nginx:Nginx 应用实战|JavaGuide
百万架构师系列文章阅读体验感更佳 原文链接:https://javaguide.net 公众号:不止极客 课程目标: Nginx 反向代理功能配置 Nginx 负载均衡实战 Nginx 动静分离配置 ...
- hbase - [04] java访问hbase
需要导入jar包 $HBASE_HOME/lib下的所有jar包 $HADOOP_HOME/share/hadoop/common的所有jar包 package com.harley.hbase.te ...
- 设计原则&模式:原型模式 Prototype(创建型)
定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.也就是说,这种不通过new关键字来产生一个对象,而是通过对象复制(Java中的clone或反序列化)来实现的模式,就叫做原型模式. ...