日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

verilog for循环_HDLBits:在线学习 Verilog (二十四 · Problem 115-119)

發(fā)布時間:2025/3/20 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 verilog for循环_HDLBits:在线学习 Verilog (二十四 · Problem 115-119) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本系列文章將和讀者一起巡禮數(shù)字邏輯在線學(xué)習(xí)網(wǎng)站 HDLBits 的教程與習(xí)題,并附上解答和一些作者個人的理解,相信無論是想 7 分鐘精通 Verilog,還是對 Verilog 和數(shù)電知識查漏補缺的同學(xué),都能從中有所收獲。

首先附上傳送門:

Rule90 - HDLBits?hdlbits.01xz.net

這部分包括 More Circuits 欄目三道題目,該欄目歸納了使用時序邏輯生成對應(yīng)輸出的題目。

Problem 115 Rule90

牛刀小試

Rule90 是一道根據(jù)一些有趣的規(guī)則來生成一維序列的題目。

規(guī)則很簡單。一維序列中元素有 1,0 兩種狀態(tài),分別對應(yīng)開,關(guān)狀態(tài)。

在每個時鐘邊沿到來時刻,元素的下一個狀態(tài)為元素相鄰兩個元素的異或。

下表更詳細(xì)地給出了跳變的規(guī)則,(可以視為狀態(tài)轉(zhuǎn)移表),元素下一個狀態(tài)可以視作輸出,輸入為元素本身的狀態(tài)與相應(yīng)兩個相鄰元素的當(dāng)前狀態(tài)。

by the way,本題題目中的 Rule90 來自于上表中的 next state 這一列: 01011010 = 8'd90。

對于需要實現(xiàn)的電路,創(chuàng)建一個擁有 512 個元素的序列 (q[511:0]),每個時鐘周期按照上述規(guī)則變換。load 信號有效時,序列更新 data 信號值為初始值。另外假設(shè)所有邊界的值為 0 (q[-1] 以及 q[512])

解答與分析

module top_module(input clk,input load,input [511:0] data,output reg[511:0] q ); int i;always @(posedge clk ) beginif(load)q <= data;else beginq[0] <= q[1] ^ 0;q[511] <= 0 ^ q[510];for(i = 1; i<511;i=i+1)q[i] <= q[i - 1] ^ q[i + 1]; endend endmodule

解答中單列了兩種特殊情況,q[0] 以及 q[511] ,因為他們的左側(cè)或者右側(cè)元素并不存在,題目中將其設(shè)定為 0.

除此之外的情況,使用 for 循環(huán),狀態(tài)轉(zhuǎn)移當(dāng)前狀態(tài)左右鄰居值的異或結(jié)果,其中左鄰居指的是高位,右鄰居指的是低位,是一種大端格式。

其實也可以不單列出特殊情況,比如本題的參考解答(原作者實在厲害,在下佩服)

module top_module(input clk,input load,input [511:0] data,output reg [511:0] q);always @(posedge clk) beginif (load)q <= data; // Load the DFFs with a value.else begin// At each clock, the DFF storing each bit position becomes the XOR of its left neighbour// and its right neighbour. Since the operation is the same for every// bit position, it can be written as a single operation on vectors.// The shifts are accomplished using part select and concatenation operators.// left right// neighbour neighbourq <= q[511:1] ^ {q[510:0], 1'b0} ;endend endmodule

異或左右鄰居矩陣,左右鄰居矩陣分別是原矩陣右移或者左移并補零得到,十分簡練。

Problem 116 Rule110

牛刀小試

Rule110 還是一道根據(jù)有趣的規(guī)則來生成一維序列的題目,比如用于:

https://en.wikipedia.org/wiki/Turing_completeness?en.wikipedia.org

規(guī)則:一維序列中元素有 1,0 兩種狀態(tài),分別對應(yīng)開,關(guān)狀態(tài)。

在每個時鐘邊沿到來時刻,元素的下一個狀態(tài)取決于元素本身的狀態(tài)與前后兩個相鄰元素的當(dāng)前狀態(tài)。下表詳細(xì)地給出了跳變的規(guī)則。

題目中的 Rule110 來自于上表中的 next state 這一列: 01101110= 8'd110。

對于需要實現(xiàn)的電路,創(chuàng)建一個擁有 512 個元素的序列 (q[511:0]),每個時鐘周期按照上述規(guī)則變換。load 信號有效時,序列更新 data 信號值為初始值。另外假設(shè)所有邊界的值為 0 (q[-1] q[512])

解答與分析

本題與上一題的區(qū)別在于沒有給出具體的此態(tài)生成關(guān)系,比如上一題中的異或。所以我們首先需要找出狀態(tài)轉(zhuǎn)移規(guī)則。我們把上述的狀態(tài)轉(zhuǎn)移表轉(zhuǎn)換為一個真值表來尋找轉(zhuǎn)換規(guī)則,真值表對應(yīng)的是三個輸入信號:left,center,right,一個輸出信號:next_state。

根據(jù)卡諾圖可以得到:OUT = Center ^ Right + (Center · ~Left )

找到轉(zhuǎn)移關(guān)系后,后續(xù)的解答就和上一題相同。

module top_module(input clk,input load,input [511:0] data,output reg[511:0] q ); int i;always @(posedge clk ) beginif(load)q <= data;else beginq[0] <= q[0];q[511] <= (q[511] ^ q[510] )|| ( q[510] );for(i = 1; i<511;i=i+1)q[i] <= (q[i] ^ q[i - 1] )|| (!q[i+1] & q[i-1]); endend endmodule

Problem 117 Conwaylift/conway's game of life 16x16

牛刀小試

作為前兩題的升級版,本題的變換工作在一個二維矩陣上,是一個二維序列生成器。

游戲規(guī)則如下:元素的下一個狀態(tài)取決于當(dāng)前狀態(tài)九宮格中的 8 個鄰居元素中 1 的個數(shù),當(dāng)鄰居有 n 個 1 時:

  • 0-1 ,元素變?yōu)?0
  • 2 ,元素保持不變
  • 3 ,元素變?yōu)?1
  • 4+ ,元素變?yōu)?0

方便做題起見,本題中的這個二維矩陣設(shè)定為 16x16,廣義上可以是無限的。

為了讓事情變得更加有趣,這個16x16 矩陣的邊界進行循環(huán)處理,回卷到對邊,打個比方,上邊界的上一行為下邊界,左邊界的左一列為右邊界。

上下邊界回卷示意,左右邊界同理

所以對元素 (0,0) 來說,共有 8 個鄰居 : (15,1), (15,0), (15,15), (0,1), (0,15), (1,1), (1,0) 以及 (1,15)。

這個 16x16 矩陣表示為 256bit 長度的向量 q,其中 q[15:0] 代表第一行,q[31:16] 代表第二行,以此類推。

HDLBit 支持使用 SystemVerilog,所以你也可以使用二維向量表示這個矩陣。load 信號有效時,更新 q 信號值為初始值 data, q 每個周期變換一次。

解答與分析

module top_module(input clk,input load,input [255:0] data,output [255:0] q ); reg [15:0] q_2d [15:0]; //2-d qwire [2:0] nghbr_num [255:0];int idx_i_d,idx_i_u,idx_j_r,idx_j_l,i,j;//count num of neighboursalways@(*) beginfor(i = 0 ; i < 16 ; i = i + 1) beginfor(j = 0 ; j < 16 ; j = j + 1) beginidx_i_u = (i == 0) ? i-1+16 :i-1; //up idxidx_i_d = (i == 15)? i+1-16 :i+1; //down idxidx_j_l = (j == 0) ? j-1+16 :j-1; //left idxidx_j_r = (j == 15)? j+1-16 :j+1; //right idxnghbr_num[i*16+j] = q_2d[idx_i_u][idx_j_l] + q_2d[idx_i_u][j ] + q_2d[idx_i_u][idx_j_r]+ q_2d[i ][idx_j_l] + q_2d[i ][idx_j_r]+ q_2d[idx_i_d][idx_j_l] + q_2d[idx_i_d][j ] + q_2d[idx_i_d][idx_j_r];endendend//next state transform base on num of neighboursalways @(posedge clk) beginif(load) begin:initfor(i = 0 ; i < 16 ; i = i + 1) beginfor(j = 0 ; j < 16 ; j = j + 1) beginq_2d[i][j] <= data[i*16+j];endendendelse begin:set_valfor(i = 0 ; i < 16 ; i = i + 1) beginfor(j = 0 ; j < 16 ; j = j + 1) beginif(nghbr_num[i*16+j] < 2)q_2d[i][j] <= 1'b0;else if (nghbr_num[i*16+j] > 3)q_2d[i][j] <= 1'b0;else if (nghbr_num[i*16+j] == 3)q_2d[i][j] <= 1'b1;elseq_2d[i][j] <= q_2d[i][j];endendendend//outputalways@(*) beginfor(i = 0 ; i < 16 ; i = i + 1) beginfor(j = 0 ; j < 16 ; j = j + 1) beginq[i*16+j] = q_2d[i][j];endendendendmodule

本題筆者采用一分為 2 的思路:

  • 統(tǒng)計矩陣中每個元素的 8 -相鄰元素中 1 的個數(shù)
  • 根據(jù)相鄰元素中的 1 的個數(shù),決定元素下一狀態(tài)的值

使用組合邏輯,采用相加的方式計算相鄰元素中 1 的個數(shù),使用一個 256 長的序列來記錄每個元素相鄰元素中 1 的個數(shù),最大為 8 個,所以每個元素使用 3 bit 來記錄。

wire [2:0] nghbr_num [255:0];

在統(tǒng)計時,需要處理邊界繞回的的特殊情況。對于邊界上的元素,根據(jù)繞回的規(guī)則確立邊界。需要特殊處理的是第一/最后一行/列。在編寫 Verilog 代碼時,可以對這幾種情況分別確立邊界。

因為不想代表顯得太冗長,這里引入了 4 個整形變量 idx_i_d, idx_i_u, idx_j_r, idx_j_l ,在不同的情況下,來確立四條邊界。

idx_i_u = (i == 0) ? i-1+16 :i-1; //up idx idx_i_d = (i == 15)? i+1-16 :i+1; //down idx idx_j_l = (j == 0) ? j-1+16 :j-1; //left idx idx_j_r = (j == 15)? j+1-16 :j+1; //right idx

使用時序邏輯,根據(jù)統(tǒng)計的結(jié)果,決定下一周期元素的值。

輸出最終結(jié)果時,將二維信號重新轉(zhuǎn)換為一維信號,Verilog 不支持直接在一維/二維信號之間賦值。

從下一題開始將進入一個漫長的狀態(tài)機欄目,我們將討論多道學(xué)習(xí)狀態(tài)機的題目。

Problem 118 Simple FSM1 / Fsm1

牛刀小試

圖中是一個有兩個狀態(tài)的摩爾型狀態(tài)機。有一個輸入信號與一個輸出信號。本題中需要實現(xiàn)圖中的狀態(tài)機,注意復(fù)位后狀態(tài)為 B,復(fù)位采用異步復(fù)位。

解答與分析

module top_module (input clk,input in,input areset,output out );// -----實現(xiàn)狀態(tài)機 endmodule

這里我們學(xué)習(xí)標(biāo)準(zhǔn)答案中的表示,采用三段式的寫法來描述這個簡單的狀態(tài)機。三段式狀態(tài)機雖然代碼會長一些,但能夠更方便地修改,并更清晰地表達狀態(tài)機的跳變與輸出規(guī)則。

使用參數(shù)來表示每個狀態(tài)。

// Give state names and assignments. I'm lazy, so I like to use decimal numbers.// It doesn't really matter what assignment is used, as long as they're unique.parameter A=0, B=1;reg state; // Ensure state and next are big enough to hold the state encoding.reg next;// A finite state machine is usually coded in three parts:// State transition logic// State flip-flops// Output logic// It is sometimes possible to combine one or more of these blobs of code// together, but be careful: Some blobs are combinational circuits, while some// are clocked (DFFs).

三段式分別指

  • 狀態(tài)跳轉(zhuǎn)邏輯
  • 狀態(tài)觸發(fā)器實現(xiàn)
  • 輸出邏輯

狀態(tài)跳轉(zhuǎn)邏輯,根據(jù)輸入信號以及當(dāng)前狀態(tài)確定狀態(tài)的次態(tài)。

// Combinational always block for state transition logic. Given the current state and inputs,// what should be next state be?// Combinational always block: Use blocking assignments.always@(*) begincase (state)A: next = in ? A : B;B: next = in ? B : A;endcaseend

狀態(tài)觸發(fā)器實現(xiàn),在時鐘邊沿實現(xiàn)狀態(tài)寄存器的跳變以及狀態(tài)復(fù)位

// Edge-triggered always block (DFFs) for state flip-flops. Asynchronous reset.always @(posedge clk, posedge areset) beginif (areset) state <= B; // Reset to state Belse state <= next; // Otherwise, cause the state to transitionend

輸出邏輯,根據(jù)當(dāng)前狀態(tài)實現(xiàn)輸出

// Combinational output logic. In this problem, an assign statement is the simplest.// In more complex circuits, a combinational always block may be more suitable.assign out = (state==B);

Problem 119 Simple FSM1 / Fsm1s

牛刀小試

實現(xiàn)一個和上一題相同,但采用同步復(fù)位的狀態(tài)機。

和上一題只是復(fù)位的方式不同,這里不再贅述實現(xiàn)代碼了。

總結(jié)

以上是生活随笔為你收集整理的verilog for循环_HDLBits:在线学习 Verilog (二十四 · Problem 115-119)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。