數字11 verilog實現通用二分法

2021-10-18 18:52:23 字數 1741 閱讀 5363

最近想做乙個通用二分法,所謂通用,就是對不同的位寬的資料都能做二分法,比如輸入4bit。能夠按照8->12->14->13的順序開始做二分法。輸入2bit,能夠按照2->3的順序做二分法。

假設輸入n,那麼就會從n/2開始做二分法。

使用verilog語言實現的話,我這裡暫時想出了一種思路。

以下面這個二分法流程為引。

程序cnt_id=0 : 比較結果為0表示二分法向下 32->1610

0000->01

0000

程序cnt_id=1 : 比較結果為1表示二分法向上 16->24 010

000-> 011

000

程序cnt_id=2 : 比較結果為0表示二分法向下 24->20 0110

00-> 0101

00

程序cnt_id=3 : 比較結果為0表示二分法向下 20->18 01010

0-> 01001

0

程序cnt_id=4 : 比較結果為1表示二分法向上 18->19 010010

-> 010011

根據以上這個流程可以總結出幾點規律:

1 每次做二分法的資料位寬只有2bit,其他bit都不變。

2 做二分法的資料位置,根據程序變化。比如程序是0時,資料只有最高位和次高位變化。資料操作依次右移。

3 做二分法的2bit資料中,高位會與比較結果相等,低位的結果都是從0變成1。

那麼,我的思路是做乙個資料刷子,這個刷子把原資料刷一下,就變成了二分之後的資料。

這個刷子是這麼做的。

首先根據異或xor的運算規則。

根據0 ^ 0 = 0,0 ^ 1 = 1 可得0 ^ n = n

根據1 ^ 0 = 1,1 ^ 1 = 0 可得1 ^ n = !n

那麼以此運算規則為基礎,根據上面總結的二分法的規律,資料bit不變的地方,我讓它異或0,bit變為比較結果的地方,我讓他異或(比較結果的取反),從0變成1的地方,我讓它異或1就可以了。

所以我構造的刷子就出來了。

[!cmp_in,1』b1]根據cnt_id右移位,其他位補0

用這個刷子,去異或原資料,比如

程序cnt_id=0 : 比較結果為0表示二分法向下 32->1610

0000(->01

0000)

我的刷子是110000,那麼110000異或100000是010000。

程序cnt_id=1 : 比較結果為1表示二分法向上 16->24 010

000 (->011

000)

我的刷子是001000,那麼001000異或010000是011000。

依次類推。

寫成**我是這麼寫的

result <= result ^ (<<(reg_width-2-cnt_id))

空位的話verilog會自動補0的。

我這個思路其實我自己感覺還有些奇怪的地方,比如這句話是不是邏輯過多的。

先記錄一下,以後有問題再回來總結。

通用二分查詢

這是極其簡單的乙個演算法,正是因為其簡單,我經常被其搞死。不管是在比賽時還是在面試時,我都在這上面栽過跟頭。因為其簡單,所以總也不願花過多時間來寫它,總想一氣呵成,但總也呵不成,於是腦袋越來越混亂,情緒越來越激動,於是悲劇隨之而來。二分查詢要求被查詢陣列是排好序的陣列,其時間複雜度為o log n ...

數字配對(二分)

給出一組數,驗證這些數中是否有兩個數的和為s 多組資料,每組資料兩行,第一行是兩個整數,n n 100,000 和s 0 s 2 32 第二行將有n個整數a1,a2,an 0 ai 2 32,1 i n 數字之間用空格隔開。每組資料輸出一行,僅乙個數字,代表有多少不同的有序數字對 ai,aj 使得a...

c語言實現的通用二分查詢演算法

cpp 二分查詢是基於排好序的演算法。複雜度低,並且很高效,由於專案中大量使用的了二分查詢,但是又不能每個業務實現乙個 因此有必要實現乙個通用的二分查詢 其主要思想 通過對已經排好序的陣列,進行資料指標的比較。const void key 需要查詢的key值 const void base,所要查詢...