已知一個(gè)加法器IP,其功能是計(jì)算兩個(gè)數(shù)的和,但這個(gè)和延遲兩個(gè)周期才會(huì)輸出?,F(xiàn)在有一串連續(xù)的數(shù)據(jù)輸入,每個(gè)周期都不間斷,試問(wèn)最少需要例化幾個(gè)上述的加法器IP,才可以實(shí)現(xiàn)累加的功能。
設(shè)計(jì)分析
實(shí)現(xiàn)累加器的加法器例化的個(gè)數(shù)。按照原文大佬的設(shè)計(jì)方法,因?yàn)閿?shù)據(jù)連續(xù)且加法器的延遲周期是2,使用使用一個(gè)實(shí)現(xiàn)累加,會(huì)有一半的數(shù)據(jù)丟失。那這樣設(shè)計(jì)他就將奇數(shù)偶數(shù)的數(shù)據(jù)進(jìn)行了分開(kāi)做一級(jí)累加,然后第二級(jí)將奇數(shù)偶數(shù)的累加結(jié)果再累加。這樣做共需消耗3個(gè)加法器。
這樣設(shè)計(jì)當(dāng)然沒(méi)問(wèn)題,但是這樣設(shè)計(jì)是否是最少呢?我先拋出我的思考,我認(rèn)為在允許少量邏輯設(shè)計(jì)的情況下,最少需要例化兩個(gè)上述的加法器IP可以實(shí)現(xiàn)累加。
如果比較極限的情況下,一個(gè)都可以,先把一串?dāng)?shù)據(jù)使用寄存器緩存,然后一個(gè)一個(gè)取出來(lái)慢慢算即可,但這樣是不太可取的,首先,數(shù)據(jù)是連續(xù)的并沒(méi)有給出數(shù)據(jù)的極限長(zhǎng)度,也就是說(shuō)不論用任何涉及存儲(chǔ)結(jié)構(gòu)進(jìn)行緩存,都沒(méi)法確保該次數(shù)據(jù)能完全被存儲(chǔ)。如果題目改成一串連續(xù)數(shù)據(jù)輸入,長(zhǎng)度最大為10,那我認(rèn)為用寄存器緩存這樣的設(shè)計(jì)是合理的。
設(shè)計(jì)架構(gòu)
回到設(shè)計(jì)思路:用兩個(gè)加法器的結(jié)構(gòu)如圖示。
設(shè)計(jì)實(shí)現(xiàn)
加法器設(shè)計(jì)
假設(shè)兩個(gè)時(shí)鐘周期延時(shí)加法器代碼如下,通過(guò)例化加法器進(jìn)行構(gòu)建累加器。
//加法器IP moduleadder #(parameterDATA_WIDTH=8)( inputclk, inputrst_n, input[DATA_WIDTH-1:0]a_in, input[DATA_WIDTH-1:0]b_in, outputreg[DATA_WIDTH-1:0]out ); reg[DATA_WIDTH-1:0]sum; always@(posedgeclkornegedgerst_n)begin if(rst_n=='d0)begin sum<=?'d0; ??????out?<=?'d0; ????end ????else?begin ??????sum?<=?a_in?+?b_in; ??????out?<=?sum; ????end ??end endmodule
累加器設(shè)計(jì)
//累加器實(shí)現(xiàn) moduleadder_for_acc #(parameterDATA_WIDTH=8) ( inputclk, inputrst_n, input[DATA_WIDTH-1:0]din, inputdin_valid, outputregdout_valid, outputreg[DATA_WIDTH-1:0]dout ); reg[DATA_WIDTH-1:0]din_r0; //打一拍 always@(posedgeclkornegedgerst_n)begin if(rst_n=='d0)begin din_r0<=?'d0; ????end ????else?if(din_valid==1'B1)begin ??????din_r0<=?din; ????end ????else?begin ??????din_r0<='d0; ????end ??end ??//adder0_valid信號(hào) ??reg?adder0_valid; ??always?@(posedge?clk?or?negedge?rst_n)begin ????if(rst_n?==?'d0)begin ??????adder0_valid?<=?'d0; ????end ????else?if(din_valid==1'B1)begin ??????adder0_valid<=!adder0_valid; ????end ????else?begin ??????adder0_valid<='d0; ????end ??end ??wire[DATA_WIDTH-1:0]?a_in?=?(adder0_valid?&&?din_valid)?din:0; ??wire[DATA_WIDTH-1:0]?b_in?=?(adder0_valid)?din_r0:0; ??wire[DATA_WIDTH-1:0]?ab_sum; ??adder?adder0_dut?( ????.clk??(clk???), ????.rst_n(rst_n?), ????.a_in?(a_in??), ????.b_in?(b_in??), ????.out??(ab_sum) ??); ??//第一級(jí)加法器輸出有效信號(hào) ??reg?[1:0]adder0_valid_dly; ??wire?ab_sum_valid?=?adder0_valid_dly[1]; ??always?@(posedge?clk?)?begin ??????adder0_valid_dly<={adder0_valid_dly[0],adder0_valid}; ??end ??wire?[DATA_WIDTH-1:0]?sum_in; ??wire?[DATA_WIDTH-1:0]?ab_sum_in?=?(ab_sum_valid)?ab_sum:0; ??wire?[DATA_WIDTH-1:0]?accsum_in?=?(ab_sum_valid)?sum_in:dout; ??adder?adder1_dut?( ????.clk??(clk??????), ????.rst_n(rst_n????), ????.a_in?(ab_sum_in), ????.b_in?(accsum_in), ????.out??(sum_in???) ??); ?? ??//第二級(jí)加法器輸出有效信號(hào) ??reg?[3:0]din_valid_r0; ??reg?[1:0]adder1_valid_dly; ??wire?adder1_outvld?=?adder1_valid_dly[1]; ??always?@(posedge?clk?)?begin ????adder1_valid_dly<={adder1_valid_dly[0],ab_sum_valid}; ??end ??//輸出 ??always?@(posedge?clk?)?begin ????din_valid_r0<={din_valid_r0[2:0],(din_valid?||?adder0_valid)}; ??end ??always?@(posedge?clk?or?negedge?rst_n)?begin ????if(rst_n?==?'d0)begin ??????dout?<=?'d0; ??????dout_valid?<=?'d0; ????end ????else?if(adder1_outvld?==?1?&&?(din_valid_r0[3]==1?&&?din_valid_r0[2]==0))begin ??????dout?<=?sum_in?; ??????dout_valid?<=?'d1; ????end ????else?begin ??????dout?<=?dout?; ??????dout_valid?<=?'d0; ????end ??end endmodule
代碼架構(gòu)設(shè)計(jì)
打拍:先對(duì)數(shù)據(jù)用寄存器緩存一拍,輸入數(shù)據(jù)暫時(shí)用in[i]表示,緩存。
第一級(jí)加法器輸入選擇valid:因?yàn)榍凹?jí)積累一拍的數(shù)據(jù),設(shè)計(jì)valid用于指示加法器的輸入數(shù)據(jù)。
第一級(jí)加法器信號(hào)輸入:根據(jù)valid信號(hào)進(jìn)行選擇數(shù)據(jù)輸入。
調(diào)用第一級(jí)加法器,同時(shí)對(duì)輸入valid信號(hào)進(jìn)行打兩拍處理,指示有效的輸出數(shù)據(jù)。
第二級(jí)加法器信號(hào)輸入:根據(jù)valid信號(hào)進(jìn)行選擇數(shù)據(jù)輸入。
調(diào)用第二級(jí)加法器,同時(shí)對(duì)輸入valid信號(hào)進(jìn)行打兩拍處理,指示有效的輸出數(shù)據(jù)。
輸出結(jié)果和valid信號(hào)。
經(jīng)過(guò)分析,目前設(shè)計(jì)延時(shí)是4拍,也即兩級(jí),這里dout和valid使用的是時(shí)序邏輯輸出,所以在輸入valid拉低后的第五個(gè)時(shí)鐘周期輸出正確的結(jié)果。
仿真測(cè)試
設(shè)計(jì)仿真測(cè)試代碼對(duì)代碼進(jìn)行測(cè)試,這里使用了遞增數(shù)測(cè)試代碼可用性,在實(shí)際測(cè)試時(shí),可通過(guò)改變DATA_LEN的大小測(cè)試單次遞增累加后的結(jié)果,后續(xù)結(jié)果依次遞增為第一次的N倍。
`timescale1ns/1ps moduleadder_for_acc_tb; //Parameters localparamDATA_WIDTH=8; localparamDATA_LEN=5; //Ports regclk=1; regrst_n=0; reg[DATA_WIDTH-1:0]din; regdin_valid=0; wiredout_valid; wire[DATA_WIDTH-1:0]dout; adder_for_acc #( .DATA_WIDTH( DATA_WIDTH) ) adder_for_acc_dut( .clk(clk), .rst_n(rst_n), .din(din), .din_valid(din_valid), .dout_valid(dout_valid), .dout(dout) ); always@(posedgeclkornegedgerst_n)begin if(rst_n=='d0)begin din<=?'d0; ??????din_valid?<=?'d0; ????end ????else?if(dout_valid?==?1)begin ??????din?<=?'d0; ??????din_valid?<=?'d1; ????end ????else?if(din?==?DATA_LEN)begin ??????din?<=?din; ??????din_valid?<=?'d0; ????end ????else?if(din?!=?DATA_LEN)begin ??????din?<=?din?+?1; ??????din_valid?<=?'d1; ????end ????else?begin ??????din?<=?din; ??????din_valid?<=?'d0; ????end ??end ??always?#5??clk?=?!?clk?; ??initial?begin ????begin ??????#100; ??????rst_n?=?1; ??????#1000; ??????$finish; ????end ??end ? endmodule
仿真截圖
仿真分析
在圖示仿真可知,累加器功能正常,在din_valid信號(hào)拉低后第五拍可得到輸出結(jié)果,功能正常。
審核編輯:劉清
-
寄存器
+關(guān)注
關(guān)注
31文章
5434瀏覽量
124443 -
存儲(chǔ)器
+關(guān)注
關(guān)注
38文章
7649瀏覽量
167353 -
仿真器
+關(guān)注
關(guān)注
14文章
1037瀏覽量
85386 -
加法器
+關(guān)注
關(guān)注
6文章
183瀏覽量
30761 -
累加器
+關(guān)注
關(guān)注
0文章
50瀏覽量
9668
原文標(biāo)題:仿真測(cè)試
文章出處:【微信號(hào):處芯積律,微信公眾號(hào):處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
計(jì)算機(jī)累加器有加法器功能嗎,累加器是什么_累加器的作用及原理介紹 精選資料推薦
加法器,加法器是什么意思
十進(jìn)制加法器,十進(jìn)制加法器工作原理是什么?
FPU加法器的設(shè)計(jì)與實(shí)現(xiàn)

同相加法器電路原理與同相加法器計(jì)算

加法器是如何實(shí)現(xiàn)的

超前進(jìn)位加法器是如何實(shí)現(xiàn)記憶的呢

數(shù)字設(shè)計(jì)筆試Verilog手撕代碼—累加器

加法器的原理及采用加法器的原因
加法器的原理是什么 加法器有什么作用

評(píng)論