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 := #; // 用十进制方式赋值: ...
随机推荐
- 在MBP上运行推理LLaMA-7B&13B模型
在MBP上运行推理LLaMA-7B模型 build this repo # build this repo git clone https://github.com/ggerganov/llama.c ...
- 闲着没事,用STC12C5616AD制作一个74hc595测试仪
手头有些特别廉价的直插74hc595,怕这些595因为廉价而质量不过关,因而萌发了制作一个测试仪的想法. 用测试仪先对595进行测试,功能正常了,再接入电路应用. 该测试仪能自动向595写入数据,再读 ...
- 使用GTD工作法提升效率
前言 近年来随着工作.副业的开展,每天要做的事情越来越多,而且还积攒了很多工作,每天大脑被各种事情充斥着,乱糟糟的,不仅效率很低,还很容易导致焦虑. 为此我一直有在寻找合适的项目管理工具,也看了一些相 ...
- threejs 实现镜面反射,只反射指定物体,背景透明
一.背景 最近在做数字孪生项目,使用threejs渲染模型,UI要求地面反射建筑物,也就是模型要有倒影. 二.调研 在官网找到一个镜面反射的例子(https://threejs.org/example ...
- c++:-8
上一节学习了C++的STL库和范型:c++:-7,本节学习c++的输入输出和流类库. I/O流 (1)程序与外界环境的信息交换 当程序与外界环境进行信息交换时,存在着两个对象:程序中的对象.文件对象. ...
- 盘点!HelloGitHub 年度热门开源项目
春节将至,HelloGitHub 也迎来了年终盘点时刻.这是一份送给开源爱好者的"年终盛宴",期待你在这里发现更多值得关注的开源佳作. 为了满足不同读者的需求,我精心准备了这期超长 ...
- Spring常用注解介绍
在Spring中,有许多高效的注解,其简化了开发并提高代码可读性,这样我们就不用再去spring.xml文件中写标签了非常方便 创建对象的注解 在Spring,有用于识别不同类型的Bean,使得Spr ...
- 从购物找零到两数之和:一道经典算法题的深度解析|LeetCode 1 两数之和
LeetCode 1 两数之和(Two Sum) 点此看全部题解 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中) 生活中的算法 还记得上次去超市购物吗?你拿着一张100元钞票 ...
- rabbitmq不同模式的区别
RPC模式
- SQL注入之报错注入
SQL注入之报错注入 一.报错注入原理 报错注入的原理基于应用程序在处理数据库查询时产生的错误信息.当应用程序执行一个含有恶意SQL代码的查询时,如果查询出错(例如,由于语法错误或权限不足),数据库系 ...