1. 程式人生 > >verilog 4位16位任意位超前進位加法器

verilog 4位16位任意位超前進位加法器

眾所周知,1+1=2,對於較小位數的加法,大家都可以在瞬間報出結果,但是如果比較大呢?13242345609745021+24234123421=?我們就需要一些運算時間來計算出結果。當然如果您是最強大腦選手,可能也能立刻報出答案。對於這種“最強大腦”選手,我們在FPGA中對應的就是效能,我們選擇成本更高的fpga比如您一開始使用的是cyclone I,現在換成了cyclone V系列產品,那麼運算速度就自然會提高。我們現在的想法就是想在同一個晶片上,減小運算的延時,從而提高系統的工作頻率,而不是通過改變器件。回想一下我們小學課上學的豎式加法運算我們想得到第k位的最終結果,就需要知道第k位的加數,被加數,以及是否進位,那麼進位又需要上一位的加數,被加數,進位數..以此類推直到第一位。這就是所謂的行波加法器了。
module add_4 ( 
input [3:0]a, 
input [3:0]b, 
input c_in, 
output [3:0] sum, 
output c_out 
); 
wire [3:0] c_tmp; 

full_adder i0 ( a[0], b[0], c_in, sum[0], c_tmp[0]); 
full_adder i1 ( a[1], b[1], c_tmp[0], sum[1], c_tmp[1] );  
full_adder i2 ( a[2], b[2], c_tmp[1], sum[2], c_tmp[2] );  
full_adder i3 ( a[3], b[3], c_tmp[2], sum[3], c_tmp[3] );  
assign c_out = c_tmp[3];
endmodule
這是我從網上找到的一張圖片,大概就是四個全加器級聯,怎麼個級聯方法呢,就是把他們的低位進位輸出連線到高位進位輸入。關於全加器,如果大家不會的話,還是先翻翻verilog書吧,建議還是先把基礎打好,因為這可以說是十分基本的內容了,任何一本verilog的書上肯定都會有的,我在這裡主要介紹的是他的加強版超前進位加法器。事實上,這個加法器需要9個門的傳輸延時,(第一個加法器需要三個,其他都是兩個),於是我們想有沒有一種方法可以快一點,讓這個傳輸門的個數少一些呢,當然是可以的。這就是我要介紹的超前進位加法器了。大家可以先自己想想,對於一個四位加法器來說,我們如何可以立刻知道第k位的進位值呢?因為如果我們知道了該位的進位值,就僅需要一個全加器也就是3個門延時就能得到了結果了,這無疑是令人興奮的。
對於一個全加器我們知道
Si =Ai ^ Bi^ Ci-1
Ci = AiBi + AiCi-1 + BiCi-1=AiBi + (Ai+Bi)Ci-1

Gi=Ai*Bi ; Pi=Ai+Bi 代入Ci =AiBi + (Ai+Bi)Ci-1
得 Ci=Gi+Gi*Ci-1

C0 = C_in
C1=G0 + P0·C0
C2=G1 + P1·C1 = G1 + P1·G0 + P1·P0 ▪C0
C3=G2 + P2·C2 = G2 + P2·G1 + P2·P1·G0 + P2·P1·P0·C0
C4=G3 + P3·C3 = G3 + P3·G2 + P3·P2·G1 + P3·P2·P1·G0 + P3·P2·P1·P0·C0
C_out=C4
現在我們只需要三個門就可以實現四位加法運算了!
module ahead_adder4
(
input cin,
input [3:0]A,
input [3:0]B,
input [3:0]G,
input [3:0]P,
output  [3:0]S,
output   cout
);

wire [3:0]C;

assign C[0]= G[0] | (cin&P[0]);
assign C[1]= G[1] | (P[1]&G[0]) | (P[1]&P[0]&cin);
assign C[2]= G[2] | (P[2]&G[1]) | (P[2]&P[1]&G[0]) | (P[2]&P[1]&P[0]&cin);
assign C[3]= G[3] | (P[3]&G[2]) | (P[3]&P[2]&G[1]) | (P[3]&P[2]&P[1]&G[0]) | (P[3]&P[2]&P[1]&P[0]&cin);

assign S[0]=A[0]^B[0]^cin;
assign S[1]=A[1]^B[1]^C[0];
assign S[2]=A[2]^B[2]^C[1];
assign S[3]=A[3]^B[3]^C[2];
assign cout=C[3];

endmodule

那麼問題來了,如何實現16位超前進位加法器呢!?有一種辦法是將4個4位超前進位加法器級聯,但實際上這是一種超前+行波的方式,並不是最快的組合!事實上我們可以根據16位加數和被加數直接寫出這四個超前進位加法器的進位值,這樣即實現了超前進位的超前進位加法器!程式碼如下:
module ahead_adder
(
input [15:0]A,
input [15:0]B,
input CIN,
output reg [15:0]S,
output reg cout 
);

wire [15:0]G=A&B;
wire [15:0]P=A|B;
reg [3:0]cin;
wire cout1;

task ahead_adder4;

input cin;
input [3:0]A;
input [3:0]B;
input [3:0]G;
input [3:0]P;
output  reg [3:0]S;
output  reg cout;
reg [3:0]C;
begin
C[0]= G[0] | (cin&P[0]);
C[1]= G[1] | (P[1]&G[0]) | (P[1]&P[0]&cin);
C[2]= G[2] | (P[2]&G[1]) | (P[2]&P[1]&G[0]) | (P[2]&P[1]&P[0]&cin);
C[3]= G[3] | (P[3]&G[2]) | (P[3]&P[2]&G[1]) | (P[3]&P[2]&P[1]&G[0]) | (P[3]&P[2]&P[1]&P[0]&cin);

S[0]=A[0]^B[0]^cin;
S[1]=A[1]^B[1]^C[0];
S[2]=A[2]^B[2]^C[1];
S[3]=A[3]^B[3]^C[2];
cout=C[3];
end
endtask
task ahead_carry;

input cin;
input [15:0]G;
input [15:0]P;
output reg [3:0]cout;
reg [3:0]G2;
reg [3:0]P2;
begin

G2[0]=G[3] | P[3]&G[2] | P[3]&P[2]&G[1] | P[3]&P[2]&P[1]&G[0];
G2[1]=G[7] | P[7]&G[6] | P[7]&P[6]&G[5] | P[7]&P[6]&P[5]&G[4];
G2[2]=G[11] | P[11]&G[10] | P[11]&P[10]&G[9] | P[11]&P[10]&P[9]&G[8];
G2[3]=G[15] | P[15]&G[14] | P[15]&P[14]&G[13] | P[15]&P[14]&P[13]&G[12];

P2[0]=P[3]&P[2]&P[1]&P[0];
P2[1]=P[7]&P[6]&P[5]&P[4];
P2[2]=P[11]&P[10]&P[9]&P[8];
P2[3]=P[15]&P[14]&P[13]&P[12];

cout[0]=G2[0] | (cin&P2[0]);
cout[1]=G2[1] | (P2[1]&G2[0]) | (P2[1]&P2[0]&cin);
cout[2]=G2[2] | (P2[2]&G2[1]) | (P2[2]&P2[1]&G2[0]) | (P2[2]&P2[1]&P2[0]&cin);
cout[3]=G2[3] | (P2[3]&G2[2]) | (P2[3]&P2[2]&G2[1]) | (P2[3]&P2[2]&P2[1]&G2[0]) | (P2[3]&P2[2]&P2[1]&P2[0]&cin);
end
endtask

[email protected](*)
begin
	ahead_carry(CIN,G[15:0],P[15:0],cin[3:0]);
	ahead_adder4 (CIN,A[3:0],B[3:0],G[3:0],P[3:0],S[3:0],cout1);//因為進位值實際上已經被算出來了,所以這個cout1就沒有實際意義
	ahead_adder4 (cin[0],A[7:4],B[7:4],G[7:4],P[7:4],S[7:4],cout1);
	ahead_adder4 (cin[1],A[11:8],B[11:8],G[11:8],P[11:8],S[11:8],cout1);
	ahead_adder4 (cin[2],A[15:12],B[15:12],G[15:12],P[15:12],S[15:12],cout);//但是這個cout有實際意義,因為超前進位算出的是四個adder的低位進位值,沒有算最後一個的高位進位,所以要保留
end
endmodule

相關推薦

verilog 416任意超前法器

眾所周知,1+1=2,對於較小位數的加法,大家都可以在瞬間報出結果,但是如果比較大呢?13242345609745021+24234123421=?我們就需要一些運算時間來計算出結果。當然如果您是最強大腦選手,可能也能立刻報出答案。對於這種“最強大腦”選手,我們在FPGA中對

(北大mooc計算機組成)32超前法器的延遲分析

由於它是有4個8位的超前進位加法器,再由一個形波進位加法器組成的所以, 對於一個8位的超前進位加法器,若要產生進位那麼只需要3個週期就好,如果還要算最後的結果當然要4個. 那麼當4個8位超前進位加法器拼在一起的是時候 需要算c8 c16 c24 順序是算了c8算c16再算c24 每個要算

carry_ahead adder 超前法器

一、1位半加器的實現 1.1 原理 半加器由兩個一位輸入相加,輸出一個結果位和進位,沒有進位輸入的加法器電路。 1.2 真值表 1.3 邏輯表示式 S = A ^ B C = A & B 1.4 Veri

任意制與10制的互轉 62制Demo

文章目錄 任意進位制轉換為10進位制 10進位制轉任意進位制 JAVA實現程式碼 任意進位制轉換為10進位制 假設一個R進位制的數為 An-1An-2An-3…A0 將其轉換為10進位制的公式為 y = An-1*Rn-1 + An-1

java中將16制字串轉化為10制數字。

網友的問題: http://topic.csdn.net/u/20081225/10/949ae344-34d5-4b5d-93ca-f57e0dda5057.html比如我有一個string str = "0xA0"; 這樣一個串,有沒有什麼辦法可以轉成char s =

使用Java把16制數轉化成10

在平時的學習中,會碰見一些進位制的轉換,如16進位制轉成10進位制,那麼如何在java程式設計中實現這些實用的功能,簡單寫一下。      16進位制數轉化成10進位制       這裡採用一個swi

162制補碼轉換為10

// // main.c //  16位2進位制補碼轉換為10進位制 // // Created by LongMa on 15/8/7. //  Copyright (c) 2015年 itcast. All rights reserved. /*  1.十進位制值 == 各位權之和; 權(用陣列儲存)

巨大的16制數轉到8制數

以下是原題問題描述  給定n個十六進位制正整數,輸出它們對應的八進位制數。輸入格式  輸入的第一行為一個正整數n (1<=n<=10)。  接下來n行,每行一個由0~9、大寫字母A~F組成的字串,表示要轉換的十六進位制正整數,每個十六進位制數長度不超過100000

forahead adder 超前法器

數電書上說道超前進位加法器,沒有仔細講。上網搜了這篇資料,摘抄下來 序列進位加法器需要一級一級的進位,進位延遲很大。先行進位加法器(也叫超前進位加法器)可以有效的減少進位延遲。     設二進位制加法器的第i位輸入為Xi, Yi, 輸出為Si, 進位輸入為Ci,進位

將10制數字轉成62制數字

將10進位制數字轉成62進位制數字 先定義62進位制的代表字元: static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b'

如何將10制資料儲存為2制資料(IMG2LCD的使用,pic2bin)

背景    fpga處理大資料時從txt讀取資料形式為2進位制或者16進位制,&readmemb/&readmemh,所以需要將資料轉換為二進位制或十六進位制存在txt中。 針對影象而言可以參考exe>IMG2LCD 下

超長的十六制數轉換為八

之前在oj上做過,今天做藍橋杯基礎練習又遇到了這題 but沒有一遍AC 基礎練習 十六進位制轉八進位制 時間限制:1.0s 記憶體限制:512.0MB 提交此題 錦囊1 錦囊2 問題描述   給定n個十六進位制正整數,輸出它們對應的八進位制數。 輸入格式   輸入的第一行為一個正整數

藍橋杯【基礎練習】十六制轉十進位制、八

十六進位制轉十進位制 問題描述   從鍵盤輸入一個不超過8位的正的十六進位制數字符串,將它轉換為正的十進位制數後輸出。   注:十六進位制數中的10~15分別用大寫的英文字母A、B、C、D、E、F表示。 樣例輸入 FFFF 樣例輸出 65535 方法一:巧用C語言的輸入輸

關於制轉換問題,10制轉換為26制;

目前有一個數n,想用A-Z組合表示出來,即 1=A,2=B,3=C,26=Z,27=AA,28=AB,等等。 首先考慮二進位制,二進位制由0和1組成,10進位制轉換為二進位制時候,用除以2取餘的方法, 仿照這種方法,我們取一個數1000,來計算它用字母表示的方法:

mysql16制資料轉換為10制資料

需求:表中的資料的16進位制儲存在資料庫中,先需要將資料按照10進位制進行輸出解決方法:使用mysql自帶的conv函式進行資料轉換語法如下:conv(N,from base ,to base)例項1:SELECT conv( '0a', 16, 10 )例項2:set @n = "0926F281";sel

藍橋杯演算法題庫 制轉換_16轉10

藍橋杯演算法題庫 16轉10進位制 題目 解題思路 題目 問題描述 *問題描述   從鍵盤輸入一個不超過8位的正的十六進位制數字符串,將它轉換為正的十進位制數後輸出。 *注:十六進位制數中的10~15分別用大寫的英文字母

數字轉換成excel列名(10制到Excel的26制的轉換函式)

真悲劇!自己寫了3個小時 這個東西居然沒寫出來!汗死!!!! 不過找到了答案,在網上找了好久好多有意思的演算法,但是遇到以Z 結尾的列名時計算錯誤 共享出來大家一起用吧!         /// <summary>         /// 將 Excle 列索

C語言,制轉換之十六制轉二進位制,完整程式碼

#include "iostream" using namespace std; #define MAX 50 int main()//十六轉二 { int elem2[MAX]; char elem16[MAX]; cout <

10制VS二進位制——大整數制轉化

題目描述    對於一個十進位制數A,將A轉換為二進位制數,然後按位逆序排列,再轉換為十進位制數B,我們乘B為A的二進位制逆序數。     例如對於十進位制數173,它的二進位制形式為10101101,逆序排列得到10110101,其十進位制數為181,181即為173的二進

Python學習:將N制數轉換為M制數

題目描述 程式設計實現將一個N進位制數轉換成M進位制數。 問題分析 將N進位制數轉換為M進位制數的一個直接的方法就是將N進位制數首先轉換為十進位制數,再從十進位制數往M進位制轉換