FPGA實現整型資料轉換成浮點數
阿新 • • 發佈:2020-12-17
技術標籤:FPGA
我用的是quartus軟體編寫的
參考文章連結:
https://blog.csdn.net/qq_21160843/article/details/83057049
IEEE754浮點數轉換網站
https://lostphp.com/hexconvert/
我主要是根據上面那一段話寫的程式碼,這裡我主要講如何實現上述的方法,通過我的程式碼進行分析。經測試20組資料後,測試結果與浮點數轉換器轉換結果相符
`
實現程式碼
在這裡插入程式碼片
```module int_to_float
(
input clk,
input rst_n,
input [ 31:0]int_number, //輸入的定點數,將其按照32位的二進位制數進行輸入
output reg [31:0]float_number //輸出的浮點數
);
wire sign; //符號位
wire[7:0]order_code; //階碼
reg [22:0]Mantissa; //尾數
reg [4:0]no_zero; //用來儲存第一個1前面的0的個數+符號位 ,例如32’d0000_0000_0000_0000_0000_0000_0001_0001,這個整型是17,前面有27個0(包含一個符號位)
//如果符號位為1,那麼no_zero的值也是27
reg [4:0]cnt; //作為一個判斷是第幾位出現第一個1的計數器,
reg [4:0]cnt_flag; //記錄當出現第一個1時,將計數器當時的值賦值給它
reg cnt_finish_flag; //一個數據前面幾個0計數完成的標誌
assign sign=int_number[31]; //判斷符號位 這個位置需要注意
assign order_code=5'd31+7'd127-no_zero;
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
no_zero=5'b0;
else
no_zero=cnt_flag;
end
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
cnt<=5'd30; //我的cnt初始值是30,因為第一位符號位,要排除,那麼就是在31個的資料裡面找1出現在哪一位,因為採用的是陣列形式,cnt[我的cnt初始值是30,
//因為第一位是符號位要排除,也是就在31位資料裡面尋找第一個1出現的位置,採用的是陣列形式,能計數到cnt[0],所以從30開始往後減
cnt_flag<=5'b0;
cnt_finish_flag<=1'b0;
end
else if(cnt_finish_flag==0) //表明還沒有找到除符號位外第一個1;進入下面的邏輯
begin
if(int_number[cnt]==1) //表明找到除符號位外第一個1
begin
cnt_flag<=5'd31-cnt;
cnt<=5'd30;
cnt_finish_flag<=1'b1;
end
else //表明還沒有找到第一個除符號位外的第一個1,然後cnt就依次減一,將cnt指向的位數往低位撥
cnt<=cnt-5'd1;
end
end
//實現尾數
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
Mantissa<=23'd0;
else if(cnt_finish_flag)
Mantissa<=(int_number<<(5'd23-(5'd31-cnt_flag))); //(5'd31-cnt_flag)代表的是當找到第一個1,所在的位數例如32’d0000_0000_0000_0000_0000_0000_0001_0001;這裡5'd31-cnt_flag)
//對應就是4,23-4=19,32’d1_0001;往左移動19位得32’d1_000_1000_0000_0000_0000_0000;Mantissa只取23位,
//Mantissa=23’d000_1000_0000_0000_0000_0000;
end
//實現位拼接
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
float_number<=32'd0;
else if(cnt_finish_flag)
float_number<={sign,order_code,Mantissa}; //將 符號位 階碼和尾數拼接起來
end
endmodule
模擬指令碼
```c
`timescale 1ns/1ns
`define time_period 20
module tb_int_to_float;
reg clk;
reg rst_n;
reg [31:0]int_number;
always #(`time_period/2)clk=~clk;
initial begin
clk=1'b0;
rst_n=1'b0;
#(`time_period/2)
rst_n =1'b1;
int_number=32'd17; //輸入要轉換得整型資料
#((`time_period/2)*100000 );
$stop;
end
int_to_float
u1(
.clk(clk),
.rst_n(rst_n),
.int_number(int_number),
.float_number()
);
endmodule
工程檔案下載地址
https://download.csdn.net/download/qq_33239106/13695873
工程檔案放在par資料夾下,程式碼檔案放在RTL資料夾,可以無需下載,將上面程式碼直接複製到你建立的工程裡面即可。