日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 處芯積律


動機(jī)

今天一個朋友問了這樣一個問題

我有一個朋友

失敗原因

首先介紹一下generate的用法,generate用于減少verilog的重復(fù)語句,批量進(jìn)行操作。

雖然0202年了,綜合工具對于for的支持已經(jīng)很好了,但是使用generate進(jìn)行for循環(huán),不僅可以實(shí)現(xiàn)普通的變量賦值,還可以批量生成assign或者always語句,它的作用實(shí)際上和宏定義是一樣的,直接將代碼展開

舉個例子,我有兩個數(shù)組reg [7:0] a [7:0]和reg [7:0] b [7:0],我需要把他們對應(yīng)元素相乘,那么可以這么做

genvar i; reg [ 7:0] a [7:0]; reg [ 7:0] b [7:0]; wire [15:0] c [7:0]; generate for(i;i<8;i++) begin assign c[i] = a[i]*b[i]; end endgenerate 

這種寫法是完全等價于下面這種寫法的

genvar i; reg [ 7:0] a [7:0]; reg [ 7:0] b [7:0]; wire [15:0] c [7:0]; assign c[0] = a[0]*b[0]; assign c[1] = a[1]*b[1]; assign c[2] = a[2]*b[2]; assign c[3] = a[3]*b[3]; assign c[4] = a[4]*b[4]; assign c[5] = a[5]*b[5]; assign c[6] = a[6]*b[6]; assign c[7] = a[7]*b[7];

如果在代碼并不多的情況下,利用插件,例如sublime的insert num,也可以快速實(shí)現(xiàn)

sublime

同樣的,generate也可以批量進(jìn)行例化,例如

module adder( input clk,rst_n, input [2:0] a,b, output [3:0] c
); logic [3:0] c_f,c_ff; always_ff @(posedge clk or negedge rst_n) begin : proc_adder if(~rst_n) begin c_f   <= '0;
 c_ff  <= '0; end else begin c_f   <= a+b;
 c_ff  <= c_f; end end assign c=c_ff; endmodule module test ( input clk, // Clock input rst_n, // Asynchronous reset active low input [2:0] a [3:0], input [2:0] b [3:0], output [3:0] c [3:0]
); genvar i; generate for (i = 0; i < 4; i++) begin adder i_adder (.clk(clk), .rst_n(rst_n), .a(a[i]), .b(b[i]), .c(c[i])); end endgenerate endmodule 

如果在仿真器中查看模塊名,模塊會被自動進(jìn)行編號

通過路徑i_test.genblk1[3].i_adder.c_f就能訪問到對應(yīng)的變量

//  Module: tb // module tb(); logic clk,rst_n; logic [2:0] a [3:0]; logic [2:0] b [3:0]; logic [3:0] c [3:0];

 test i_test (.clk(clk), .rst_n(rst_n), .a(a), .b(b), .c(c)); initial begin clk <= '0; forever begin #5 clk <= ~clk; end end initial begin rst_n <= '0; repeat(5) @(posedge clk);
 rst_n <= '1; end initial begin a <= '{4{'0}};
 b <= '{4{'0}};
 @(posedge clk iff rst_n); for (int i = 0; i<4 ; i++ ) begin a[i] <= i;
 b[i] <= i; end repeat(5) @(posedge clk); $display("c_f[3]:%h",i_test.genblk1[3].i_adder.c_f);
 @(posedge clk); $stop(); end endmodule: tb

可以看到訪問成功

如果通過文章開頭說的方式,就會出現(xiàn)錯誤

for (int i = 0; i<4 ; i++ ) begin $display("c_f[%0d]:%h",i_test.genblk1[i].i_adder.c_f); end 

其實(shí)主要原因是,這個genblk1根本就不是一個數(shù)組,也就無法通過這種索引的方法訪問到對應(yīng)變量

解決辦法

目前我能想到的方法就是通過uvm提供的函數(shù)uvm_hdl_read實(shí)現(xiàn),他在底層通過dpi從外部訪問變量,因此可以通過字符串訪問到對應(yīng)的變量。

uvm_hdl_read的原型是

import "DPI-C" context function int uvm_hdl_read( string path, output uvm_hdl_data_t 	value
)

返回的uvm_hdl_data_t在uvm中的定義是

parameter int UVM_HDL_MAX_WIDTH = `UVM_HDL_MAX_WIDTH; typedef  logic [UVM_HDL_MAX_WIDTH-1:0] uvm_hdl_data_t;

因此,我們可以通過下面的代碼訪問genblk1中的變量

for (int i = 0; i<4 ; i++ ) begin uvm_hdl_read($sformatf("tb.i_test.genblk1[%0d].i_adder.c_f",i),temp) $display("c_f[%0d]:%2h",i,temp); end 

有幾個注意事項(xiàng)

  1. 在描述路徑時,要傳入絕對路徑,不能使用相對路徑
  2. 在描述路徑時,使用%0d,否則字符串會與真實(shí)路徑不匹配

可以看到訪問成功

uvm讀取

下面給出完整代碼

//  Module: tb // module tb(); import uvm_pkg::*; `include "uvm_macros.svh" logic clk,rst_n; logic [2:0] a [3:0]; logic [2:0] b [3:0]; logic [3:0] c [3:0];

 test i_test (.clk(clk), .rst_n(rst_n), .a(a), .b(b), .c(c)); initial begin clk <= '0; forever begin #5 clk <= ~clk; end end initial begin rst_n <= '0; repeat(5) @(posedge clk);
 rst_n <= '1; end initial begin uvm_hdl_data_t temp;
 a <= '{4{'0}};
 b <= '{4{'0}};
 @(posedge clk iff rst_n); for (int i = 0; i<4 ; i++ ) begin a[i] <= i;
 b[i] <= i; end repeat(5) @(posedge clk); $display("c_f[3]:%h",i_test.genblk1[3].i_adder.c_f); for (int i = 0; i<4 ; i++ ) begin uvm_hdl_read($sformatf("tb.i_test.genblk1[%0d].i_adder.c_f",i),temp) $display("c_f[%0d]:%2h",i,temp); end @(posedge clk); $stop(); end endmodule: tb

當(dāng)然,uvm不僅提供了讀取,還提供了全家桶服務(wù),forcedeposit一應(yīng)俱全

如果有更好的辦法,歡迎留言


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉