请教systemverilog中的interface问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请教systemverilog中的interface问题相关的知识,希望对你有一定的参考价值。
参考技术A 普通的模块使用法:注意我们这里只实现了部分功能。。。。不是完全的读写模块。。。。module mem_core(
input logic wen,
input logic ren,
output logic mrdy=1,
input logic [7:0] addr,
input logic [7:0] mem_din, //写进mem
output logic [7:0] mem_dout, //从mem读出
output logic status,
input logic clk);
logic[7:0] mem [7:0]; //初始化一个mem
initial $readmemh("d:/init.txt",mem); //d:/init.txt 文件中是 @01 10 。
//或者 assign mem [2'h01]=8'b00000111; 注意这里一定要用 initial 或者assign等语句,不能直接=
task reply_read(input logic [7:0] data, integer delay);
#delay;
@(negedge clk)
mrdy=1'b0;
mem_dout=data; //从图中可看出这两句话几乎同时执行。
@(negedge clk)
mrdy=1'b1;
endtask
always@(negedge ren) reply_read(mem[addr],10);
endmodule
module cpu_core(
output logic wen=1,
output logic ren=1,
input logic mrdy,
output logic [7:0] addr=0,
input logic [7:0] cpu_din,
output logic [7:0] cpu_dout,
output logic status=0,
input logic clk);
task read_memory(input logic [7:0] raddr, output logic [7:0] data);
@(posedge clk);
ren=1'b0;
addr=raddr;
@(negedge mrdy);
@(posedge clk);
data=cpu_din;
ren=1'b1;
endtask
initial begin
logic[7:0] read_data;
read_memory(2'h01, read_data);
$display("Read Result", $time,read_data);
end
endmodule
module top;
logic mrdy,wen,ren;
logic[7:0] addr,d1,d2;
wor status;
logic clk=0;
mem_core mem(.*, .mem_din(d1), .mem_dout(d2)); //采用*对同名的信号做默认连接
cpu_core cpu(.*, .cpu_din(d2), .cpu_dout(d1));
initial for(int i=0;i<=255;i++) #1 clk=!clk;
endmodule
另外,SystemVerilog引入一个重要的数据类型:interface。其主要作用有两个:一是简化模块之间的连接;二是实现类和模块之间的通信;
随着复杂度的提高,模块间互联变得复杂,SV引入接口,代表一捆连线的结构,具有智能同步和连接功能的代码;
接口(interface)为硬件模块的端口提供了一个标准化的封装方式。
用interface来封装接口的信号和功能。interface的定
义是独立于模块的,通过关键字interface和endinterface包起来。此外,interface里面还可以
带时钟、断言、方法等定义。
一个interface 也可以有input,output或是inout端口。当interface例化时,只有当变量或是线网声明在一个interface的端口列表中才能通过名字或是位置来互连.本回答被提问者采纳
UVM Primer - SystemVerilog interfaces 和 BFM
tinyalu_pkg.sv
package tinyalu_pkg;
typedef enum bit[2:0] {no_op = 3‘b000,
add_op = 3‘b001,
and_op = 3‘b010,
xor_op = 3‘b011,
mul_op = 3‘b100,
rst_op = 3‘b111} operation_t;
endpackage : tinyalu_pkg
tinyalu_bfm.sv
interface tinyalu_bfm; import tinyalu_pkg::*; byte unsigned A; byte unsigned B; bit clk; bit reset_n; wire [2:0] op; bit start; wire done; wire [15:0] result; operation_t op_set; assign op = op_set; initial begin clk = 0; forever begin #10; clk = ~clk; end end task reset_alu(); reset_n = 1‘b0; @(negedge clk); @(negedge clk); reset_n = 1‘b1; start = 1‘b0; endtask : reset_alu task send_op(input byte iA, input byte iB, input operation_t iop, output shortint alu_result); op_set = iop; if (iop == rst_op) begin @(posedge clk); reset_n = 1‘b0; start = 1‘b0; @(posedge clk); #1; reset_n = 1‘b1; end else begin @(negedge clk); A = iA; B = iB; start = 1‘b1; if (iop == no_op) begin @(posedge clk); #1; start = 1‘b0; end else begin do @(negedge clk); while (done == 0); start = 1‘b0; end end // else: !if(iop == rst_op) endtask : send_op endinterface : tinyalu_bfm
top.sv
module top; tinyalu_bfm bfm(); tester tester_i (bfm); coverage coverage_i (bfm); scoreboard scoreboard_i(bfm); tinyalu DUT (.A(bfm.A), .B(bfm.B), .op(bfm.op), .clk(bfm.clk), .reset_n(bfm.reset_n), .start(bfm.start), .done(bfm.done), .result(bfm.result)); endmodule : top
scoreboard.sv
module scoreboard(tinyalu_bfm bfm); import tinyalu_pkg::*; always @(posedge bfm.done) begin shortint predicted_result; case (bfm.op_set) add_op: predicted_result = bfm.A + bfm.B; and_op: predicted_result = bfm.A & bfm.B; xor_op: predicted_result = bfm.A ^ bfm.B; mul_op: predicted_result = bfm.A * bfm.B; endcase // case (op_set) if ((bfm.op_set != no_op) && (bfm.op_set != rst_op)) if (predicted_result != bfm.result) $error ("FAILED: A: %0h B: %0h op: %s result: %0h", bfm.A, bfm.B, bfm.op_set.name(), bfm.result); end endmodule : scoreboard
tester.sv
module tester(tinyalu_bfm bfm); import tinyalu_pkg::*; function operation_t get_op(); bit [2:0] op_choice; op_choice = $random; case (op_choice) 3‘b000 : return no_op; 3‘b001 : return add_op; 3‘b010 : return and_op; 3‘b011 : return xor_op; 3‘b100 : return mul_op; 3‘b101 : return no_op; 3‘b110 : return rst_op; 3‘b111 : return rst_op; endcase // case (op_choice) endfunction : get_op function byte get_data(); bit [1:0] zero_ones; zero_ones = $random; if (zero_ones == 2‘b00) return 8‘h00; else if (zero_ones == 2‘b11) return 8‘hFF; else return $random; endfunction : get_data initial begin byte unsigned iA; byte unsigned iB; operation_t op_set; shortint result; bfm.reset_alu(); repeat (1000) begin : random_loop op_set = get_op(); iA = get_data(); iB = get_data(); bfm.send_op(iA, iB, op_set, result); end : random_loop $stop; end // initial begin endmodule : tester
coverage.sv
module coverage(tinyalu_bfm bfm); import tinyalu_pkg::*; byte unsigned A; byte unsigned B; operation_t op_set; covergroup op_cov; coverpoint op_set { bins single_cycle[] = {[add_op : xor_op], rst_op,no_op}; bins multi_cycle = {mul_op}; bins opn_rst[] = ([add_op:no_op] => rst_op); bins rst_opn[] = (rst_op => [add_op:no_op]); bins sngl_mul[] = ([add_op:xor_op],no_op => mul_op); bins mul_sngl[] = (mul_op => [add_op:xor_op], no_op); bins twoops[] = ([add_op:no_op] [* 2]); bins manymult = (mul_op [* 3:5]); } endgroup covergroup zeros_or_ones_on_ops; all_ops : coverpoint op_set { ignore_bins null_ops = {rst_op, no_op};} a_leg: coverpoint A { bins zeros = {‘h00}; bins others= {[‘h01:‘hFE]}; bins ones = {‘hFF}; } b_leg: coverpoint B { bins zeros = {‘h00}; bins others= {[‘h01:‘hFE]}; bins ones = {‘hFF}; } op_00_FF: cross a_leg, b_leg, all_ops { bins add_00 = binsof (all_ops) intersect {add_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins add_FF = binsof (all_ops) intersect {add_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins and_00 = binsof (all_ops) intersect {and_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins and_FF = binsof (all_ops) intersect {and_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins xor_00 = binsof (all_ops) intersect {xor_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins xor_FF = binsof (all_ops) intersect {xor_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins mul_00 = binsof (all_ops) intersect {mul_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins mul_FF = binsof (all_ops) intersect {mul_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins mul_max = binsof (all_ops) intersect {mul_op} && (binsof (a_leg.ones) && binsof (b_leg.ones)); ignore_bins others_only = binsof(a_leg.others) && binsof(b_leg.others); } endgroup op_cov oc; zeros_or_ones_on_ops c_00_FF; initial begin : coverage_block oc = new(); c_00_FF = new(); forever begin : sampling_block @(negedge bfm.clk); A = bfm.A; B = bfm.B; op_set = bfm.op_set; oc.sample(); c_00_FF.sample(); end : sampling_block end : coverage_block endmodule : coverage
以上是关于请教systemverilog中的interface问题的主要内容,如果未能解决你的问题,请参考以下文章