序文:
このコラムは、デジタル フロントエンドの秋採用者向けに、頻繁に行われるペン インタビューの手引きコード質問を記録することを目的としており、このコラムのすべての記事には原理分析、コードと波形が提供されており、すべてのコードは私自身によって検証されています。
ディレクトリは次のとおりです。
1. デジタルICハンドティアコード分周器(任意の偶数分周)
2. デジタル IC ハンドティアコード分周器 (任意の奇数分周)
3. デジタル IC ハンドティアコード分周器 (任意の 10 進分周)
4.デジタルICハンドティアリングコード - 非同期リセットと同期リリース
5.デジタルICハンドティアコード - エッジ検出(立ち上がりエッジ、立ち下がりエッジ、ダブルエッジ)
6. デジタルICハンドティアリングコード列検出(ステートマシン書き込み方式)
7. デジタルICハンドティアリングコード列検出(シフトレジスタ書き込み方式)
8. デジタルICティアリングコード - 半加算器、全加算器
9. デジタル IC ハンド ティアリング コード - シリアルからパラレル、パラレルからシリアル
10.デジタルICハンドティアリングコード-データビット幅変換器(幅-狭幅、狭幅変換)
11. デジタル IC ハンド ティアリング コード - 有限状態マシン FSM - 飲料マシン
12.デジタルICハンドティアコード - ハンドシェイク信号(READY-VALID)
13. デジタル IC ハンド ティアリング コード - 水ハンドシェイク (ハンドシェイクを使用してパイプラインの中断と背圧の問題を解決します)
14. デジタル IC ハンド テアリング コード - Telink マイクロ筆記試験問題
15. デジタル IC 手引きコード - Pingtouge 技術最終面手引き本当の質問
16.デジタルICマニュアルティアリングコード-Zhaoyiイノベーション筆記試験実際の質問
17. デジタル IC ハンド ティアリング コード - Espressif Technology 筆記試験実際の問題 (4 回の頻度)
18. デジタル IC ティアリング コード - デュアルポート RAM (デュアルポート RAM)
...継続的に更新
ハンドテアリング コードに関するその他の質問については、 デジタル IC ハンドテアリング コード - 質問バンクにアクセスしてください。
目次
トピックの説明
連続データ ストリームを入力して、256 データ ストリームごとの合計値を取得します。タイミング ダイアグラムは次のとおりです。
入力は i0、i1、i2、…、i253、i254、…であり、1 クロック サイクルに相当し、出力 sum0 は i0 +i2+….+i254 (間隔ごとに加算) の合計値、sum1 は i1+i3+ です。 …. +i255、sum2 は i2+i4+….+i256 など、各出力は 1 クロック サイクルを占有し、Sum0 と i0 の間の相対遅延関係は任意です。入力 i0、i1、i254、... が 8 ビット値であると仮定し、出力合計が精度を失わない適切なビット幅を選択し、最大限のリソースで上記の要件を達成するために Verilog 言語を使用してください。あなたの考え方を保存します。
問題解決のアイデア
この質問の要約は実際には比較的単純ですが、重要なのは、要件を達成するために最もリソース効率の高い方法を使用することです。入力はすべて 8 ビットで、sum0 と sum1 は i0 から i255 までで、256 個の 8 ビット数値が加算されます。したがって、256 個の 8 ビット数値の加算は 16 ビット数値で表現する必要があるため、合計を 15 ビットに設定します。そして、次のようなルールがあります。
sum2=sum0-i0+i256、sum3=sum1-i1+i257
深さ 257*8 ビットの空間 datain_store を使用して i0 ~ i256 を格納すると、値が入力されるたびに、datain_store が 8 ビットシフトして新しい受信数値を格納します。次に 2 つの合計を使用します。1 つの合計は奇数 128 項目の合計を出力し、もう 1 つの合計は偶数 128 項目の合計を出力します。
コード
module pip_sum(
input clk ,
input rstn ,
input [7:0] datain ,
input datain_ena ,
output [14:0] sum ,
output dataout_ena
);
reg [8*257-1:0] datain_store; //DEPTH = 2056
reg [7:0] count;
reg [14:0] sum_odd,sum_even;
reg datain_ena_onebeat;
reg flag;
always @(posedge clk)begin
if(datain_ena)begin
datain_store <= {datain_store[8*256-1:0],datain}; //left shift 8bit, store datain in low 8bit
end
end
always @(posedge clk)begin
if(!rstn)begin
count <= 8'd0;
end
else if(datain_ena_onebeat == 1'b1 && count < 8'd255)begin
count <= count + 1'b1;
end
else if(datain_ena_onebeat == 1'b1 && count == 8'd255)begin
count <= 8'd0;
end
end
always @(posedge clk)begin
if(!rstn)
flag <= 1'b0;
else if(count == 8'd255)
flag <= 1'b1; //
end
wire [7:0] look;
assign look = datain_store[7:0];
always @(posedge clk)begin
if(!rstn)begin
sum_odd <= 15'd0;
sum_even <= 15'd0;
end
else begin
datain_ena_onebeat <= datain_ena;
if(datain_ena_onebeat)
case(count[0])
0:begin
if(flag==0)
sum_even <= sum_even + datain_store[7:0];
else
sum_even <= sum_even - datain_store[8*257-1:8*256] + datain_store[7:0];
end
1:begin
if(flag==0)
sum_odd <= sum_odd + datain_store[7:0];
else
sum_odd <= sum_odd - datain_store[8*257-1:8*256] + datain_store[7:0];
end
endcase
end
end
reg [14:0] sum_odd_onebeat,sum_even_onebeat;
always @(posedge clk)begin
sum_odd_onebeat <= sum_odd;
sum_even_onebeat <= sum_even;
end
assign sum = (count[0]) ? sum_odd_onebeat: sum_even_onebeat;
assign dataout_ena = flag;
endmodule
テストベンチ
module pip_sum_tb();
reg clk,rstn;
reg [15:0] count;
reg [7:0] datain;
reg datain_ena;
wire [14:0] sum;
wire dataout_ena;
always #5 clk <= ~clk;
initial begin
clk <= 1'b0;
rstn <= 1'b0;
#16
rstn <= 1'b1;
#20
datain_ena <= 1'b1;
#10000
$finish();
end
initial begin
datain <= 8'd0;
count <= 1'b0;
forever begin
@(posedge clk)begin
if(datain_ena == 1)begin
if(count < 255)begin
datain <= 1'b0;
end
else
datain <= datain + 1'b1;
count <= count + 1'b1;
end
end
end
end
//dump fsdb
initial begin
$fsdbDumpfile("pip_sum.fsdb");
$fsdbDumpvars(0);
end
pip_sum u_pip_sum(
.clk (clk) ,
.rstn (rstn) ,
.datain (datain) ,
.datain_ena (datain_ena),
.sum (sum) ,
.dataout_ena (dataout_ena)
);
endmodule
出力波形
結果の正確さを容易にするために、datain の最初の 256 サイクルを 0 にして、出力 sum0 と sum1 が両方とも 0 になるようにし、その後 datain を正の整数シーケンスとしてインクリメントします。出力結果からわかるように、sum0=sum1=0、sum2=sum0-i0+i256=0-0+1=1; sum3=sum1-i1+i257=0-0+ という予想と一致しています。 2=2 などです。
ハンドテアリング コードに関するその他の質問については、 デジタル IC ハンドテアリング コード - 質問バンクにアクセスしてください。