以按行寫按列讀的交織器為例:
//按c語言寫法
always@(posedge clk or negedge rstn)
begin
if(!rstn)
begin
rdata<=0;
end elseif(
!w_r)begin//寫入
for(line=0;line<=rom_depth;line=line+1)
for(column=0;column<=rom_width;column=column+1)
memory[line]
[column]
<=wdata;
end else
if(w_r) begin//讀出
for(column=0;column<=rom_width;column=column+1)
for(line=0;line<=rom_depth;line=line+1)
rdata<=memory[line]
[column]
; end else begin
rdata<=1'bx;
endend
但以上語句是不可綜合的。
拆解思路一:硬體電路要時刻考慮時序,我們用乙個時鐘驅動計數器累加,由計數器的不同數值來觸發事件,可綜合語句case語句來做觸發,例如
always@(posedge clk)
begin
if(addr==2'b11)begin
addr <= 2'b00;
end else
else begin
addr <= addr + 1'b1;
endendcase(addr)
00: rdata <= memory[00]
[7:0]
;01: rdata <= memory[01]
[7:0]
;10: rdata <= memory[10]
[7:0]
;11: rdata <= memory[11]
[7:0]
;//以上**就等效於
for(addr=0;addr<=3;addr++)
rdata=memory[addr]
[7:0]
;
always@(posedge clk or negedge rstn)
begin
if(!rstn)begin
column <= 3'b0;
line <= 3'b0;
end else if(~w_r) begin//寫入資料
if(column==rom_width-1)begin
//完成一次內層巢狀的迴圈
//此時寫完了一行,line++
column <= 3'b0;
if(line==rom_depth-1)begin
line <= 3'b0;
end else begin
line <= line + 3'b001;
endend else begin
column <= column + 3'b001;
end
memory[line]
[column]
<= wdata;
end else
if(w_r) begin
//讀出資料
if(line==rom_depth-1)begin
//完成一次內層巢狀的迴圈
//讀完了一列,column++
line <= 3'b0;
if(column==rom_width-1)begin
column <= 3'b0;
end else begin
column <= column + 3'b001;
endend else begin
line <= line + 3'b001;
end
rdata <= memory[line]
[column]
; end
end
寫for迴圈注意的要點
(1)從最大的不同點進行分類:本例子特點為按行寫按列讀,寫入時先固定一行,掃瞄列寫入,因此外層迴圈變數為行,內層巢狀為列;讀出時按列讀出,先固定一列,掃瞄行讀出,因此外層迴圈變數為列,內層為行。
若行寬=列深,則行列是對稱的,可以對其進行降維,也就是說不以讀寫行為作為分類,將行列互換即可。
if(~w_r) begin
//write
memory[line]
[column]
<=wdata;
end else if(w_r) begin
//read
rdata<=memory[column]
[line]
; end
(2)注意邊界:例如[7:0]line,line最大值為255,實際上line==255 保持了乙個時鐘週期;
若約束條件為 if (line= =256),要分情況討論
line位寬為[8:0]時,line= =256會保持乙個週期,但儲存器實際上沒有這個位址,導致寫入失效,讀出為高阻;
line位寬為[7:0]時,line++會回0,if (line= =256)內的語句永遠不會被執行。
(3)先判斷後加/先加後判斷:由於(2)所述的邊界問題,會有不同的情形
一般情況下,由於變數的位寬限制,會先判斷後自加
if
(line==rom_depth-1)begin
line <= 3'b0;
end else begin
line <= line +1'b1;
end
但有些情況下,可能會先加後判斷,例如在連續讀寫資料時,位址的跳位要求
begin
line <= line + 9'h20;
if(line==256)begin
line <= 9'h0;
endend
上例中,連續讀32位,第一次為讀取位址為[31:0],下一次line為32,64,96,128,160,196,224,256,line=224時,整個memory的資料已經讀完了,因此要再加一次32使之回0。如果先判斷後自加,則line==256會保持乙個時鐘週期,導致讀出為高阻。為消除這種狀況,應使line= =256後立即回0(仍在乙個時鐘週期之內)。 002 硬體基礎電路 7805電路
lm78xx系列 輸出電流 1a 輸出電壓 5,6,8,9,10,11,12,15,18,24v 那麼平時我們使用7805都是使用9v或者12v甚至24v電壓輸入的,這樣如果按照上面的圖直接輸出會發熱得很燙。按照平時接的圖先來換算,如下圖 假如我們輸入12v,輸出5v電壓,電路中的電流是0.3a。那...
硬體電路之開關
開關分為機械開關和電子開關 例如三極體,流控流。由自己內部的電器控制開關 機械開關為普通的開關,在開關閉合或者斷開的一瞬間,會出現尖峰電壓或者浪湧電流,即高電伏。會對後面的負載產生影響。所以一般在後面加上乙個電容來濾波。當5v交流電源接通時,a點的電壓如圖上,對電容進行充電,電容電壓上公升逐漸緩慢,...
硬體電路,AD DC電路中元器件的作用
熱敏電阻 功率型ntc熱敏電阻多用於電源抑制浪湧。1 在ac220v輸入端串聯熱敏電阻,在電路電源接通瞬間,電路中會產生比正常工作時高出許多倍的浪湧電流,而ntc熱敏電阻器的初始阻值較大,可以抑制電路中過大的電流,從而保護其電源電路及負載。壓敏電阻 是一種具有非線性伏安特性的電阻器件,主要用於在電路...