- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, all.
I want to use Avalon Verification IP Suite to check a Qsys custom componet, which have an Avalon salve interface and a Avalon conduit interface connecting a LSI. I wrote this program to test if the custom component can give right response to the Avalon Master BFM.
//Console messaging level
`define VERBOSITY VERBOSITY_INFO
//BFM hierachy
`define CLK_BFM top.tb.clock_source
`define RST_BFM top.tb.reset_source
`define MM_MASTER top.tb.avalon_mm_master
`define CONDUIT_BFM top.tb.conduit_bfm
module test_program();
import verbosity_pkg::*;
import avalon_mm_pkg::*;
event start_test;
event end_test;
//----------------------------------------------------------------------------------
// Set verbosity before the test starts
// Qsys-generated testbench activates clock and reset BMFs
//----------------------------------------------------------------------------------
initial begin
set_verbosity(`VERBOSITY);
// initialize BFMS
`MM_MASTER.init();
end
//----------------------------------------------------------------------------------
// Main test block
//----------------------------------------------------------------------------------
initial begin
// wait for reset inactive
wait(`RST_BFM.reset == 1);
-> start_test;
end
initial begin
@ start_test;
// start write access
`MM_MASTER.set_command_request(REQ_WRITE);
`MM_MASTER.set_command_address(16'h0);
`MM_MASTER.set_command_idle(2,0);
`MM_MASTER.set_command_init_latency(0);
`MM_MASTER.set_command_data(32'h0,0);
`MM_MASTER.push_command();
end
endmodule
Although this program can be compiled by ModelSim with no error, but it seems the write access was not started. Can you give me some hints or some examples about how to test custom components wit Avalon IP verification suite? Regards, feng
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi feng,
Your code enqueues a transaction, but it does not wait for it to complete, so Modelsim exits too soon. Here's a couple of tasks I use:
// ============================================================
// Tasks
// ============================================================
//
// Avalon-MM single-transaction read and write procedures.
//
// ------------------------------------------------------------
task avalon_write (
// ------------------------------------------------------------
input addr,
input data
);
begin
// Construct the BFM request
`BFM.set_command_request(REQ_WRITE);
`BFM.set_command_idle(0, 0);
`BFM.set_command_init_latency(0);
`BFM.set_command_address(addr);
`BFM.set_command_byte_enable('1,0);
`BFM.set_command_data(data, 0);
// Queue the command
`BFM.push_command();
// Wait until the transaction has completed
while (`BFM.get_response_queue_size() != 1)
@(posedge clk);
// Dequeue the response and discard
`BFM.pop_response();
end
endtask
// ------------------------------------------------------------
task avalon_read (
// ------------------------------------------------------------
input addr,
output data
);
begin
// Construct the BFM request
`BFM.set_command_request(REQ_READ);
`BFM.set_command_idle(0, 0);
`BFM.set_command_init_latency(0);
`BFM.set_command_address(addr);
`BFM.set_command_byte_enable('1,0);
`BFM.set_command_data(0, 0);
// Queue the command
`BFM.push_command();
// Wait until the transaction has completed
while (`BFM.get_response_queue_size() != 1)
@(posedge clk);
// Dequeue the response and return the data
`BFM.pop_response();
data = `BFM.get_response_data(0);
end
endtask
Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Hi feng, Your code enqueues a transaction, but it does not wait for it to complete, so Modelsim exits too soon. Here's a couple of tasks I use:
// ============================================================
// Tasks
// ============================================================
//
// Avalon-MM single-transaction read and write procedures.
//
// ------------------------------------------------------------
task avalon_write (
// ------------------------------------------------------------
input addr,
input data
);
begin
// Construct the BFM request
`BFM.set_command_request(REQ_WRITE);
`BFM.set_command_idle(0, 0);
`BFM.set_command_init_latency(0);
`BFM.set_command_address(addr);
`BFM.set_command_byte_enable('1,0);
`BFM.set_command_data(data, 0);
// Queue the command
`BFM.push_command();
// Wait until the transaction has completed
while (`BFM.get_response_queue_size() != 1)
@(posedge clk);
// Dequeue the response and discard
`BFM.pop_response();
end
endtask
// ------------------------------------------------------------
task avalon_read (
// ------------------------------------------------------------
input addr,
output data
);
begin
// Construct the BFM request
`BFM.set_command_request(REQ_READ);
`BFM.set_command_idle(0, 0);
`BFM.set_command_init_latency(0);
`BFM.set_command_address(addr);
`BFM.set_command_byte_enable('1,0);
`BFM.set_command_data(0, 0);
// Queue the command
`BFM.push_command();
// Wait until the transaction has completed
while (`BFM.get_response_queue_size() != 1)
@(posedge clk);
// Dequeue the response and return the data
`BFM.pop_response();
data = `BFM.get_response_data(0);
end
endtask
Cheers, Dave --- Quote End --- I solved the problem using your tasks. Thanks, Dave. And I have another question. This custom component has an Avalon conduit interface connecting a LSI. I read the Conduit BFM section, and didn't find the right function. Can you tell me how to set the values of signals from the LSI? Best regards, feng
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I solved the problem using your tasks. Thanks, Dave. --- Quote End --- Great! --- Quote Start --- And I have another question. This custom component has an Avalon conduit interface connecting a LSI. I read the Conduit BFM section, and didn't find the right function. Can you tell me how to set the values of signals from the LSI? --- Quote End --- Don't use their test_bench() module, use your own. Lets say your design is called sopc_system, then sopc_system.v contains a module called test_bench() at the end of it. Copy the contents of that testbench into your top-level testbench, and adjust the path to the BFM accordingly. Then drive or read the conduit interfaces on the sopc_system module directly. Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your reply, Dave.
I'm using Quartus II 11.0 Web Edition, and I can't find the test_bench() module in my design file. Is the test_bench() module produced automatically by Qsys? Regards, feng- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I'm using Quartus II 11.0 Web Edition, and I can't find the test_bench() module in my design file. Is the test_bench() module produced automatically by Qsys? --- Quote End --- Yes. Look at your own code ... `define CLK_BFM top.tb.clock_source The 'tb' entry in that hierarchy is the test_bench() component you want to copy and eliminate from the design. You'll copy the clock generator, the reset generator, and the Qsys system instance, and then you will have access to the ports on the Qsys system instance, so you can manipulate the exported ports. Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, Dave.
I'll try that. Regards, feng- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I'll try that. --- Quote End --- Use the Modelsim GUI to navigate to the component in the hierarchy. It'll tell you what file its in (you might be able to double-click to bring the file into the Modelsim editor). Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Really thanks for your reply, Dave.
Because I'm not familiar with ModelSim, so I don't know how to navigate to component. But I can find the files in my design folder. Regards, feng- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks guys. This thread helped my issue.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
this problem looks to be solved. My problem is very similar, so I don't want to start a new topic for my question. I would like to use 2 Avalon MM BFMs in my Simulation. First BFM should write data, the second one - read data. It is not difficult to get the simulation running with one BFM is doing both tasks, but what should I do differently to get 2 BFMS running? Let's say, that my BFMs are defined as: `define FIRST_BFM tb.simulation_inst.mm_master_bfm_0 `define SEC_BFM tb.simulation_inst.mm_master_bfm_1 When I change the write task to use SEC_BFM instead of FIRST_BFM I got this error and simulation fails:# 416198192: FAILURE: top.tb.simulation_inst.mm_master_bfm_1.request_timeout.timeout_thread: Command phase timeout- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm not sure what your code looks like.
I've written a tutorial here that has read/write procedures for a single BFM: http://www.alterawiki.com/wiki/using_the_usb-blaster_as_an_sopc/qsys_avalon-mm_master_tutorial Start with that, and then add the second BFM. So long as the read/write procedures use their own variables, I don't see why you can't have multiple masters. Cheers, Dave- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, your tutorial is great, I have seen it already and learned a lot. There are few tutorials for single BFM, but nothing for two or more. Even in Avalon Verification IP Suite User Guide is described simulation with only one BFM.
Here is my task. Without commented push commands it works fine. Now it produces already mentioned error. task master_set_and_push_command; input Request_t request; input [`AV_ADDRESS_W-1:0] addr; input [`AV_DATA_W-1:0] data; input [`AV_NUMSYMBOLS-1:0] byte_enable; input [`AV_DATA_W-1:0] idle; input [31:0] init_latency; begin if (request == REQ_WRITE) begin tb.simulation_inst.mm_master_bfm_0.set_command_request(request); tb.simulation_inst.mm_master_bfm_0.set_command_idle(idle, `INDEX_ZERO); tb.simulation_inst.mm_master_bfm_0.set_command_init_latency(init_latency); tb.simulation_inst.mm_master_bfm_0.set_command_address(addr); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable,`INDEX_ZERO); tb.simulation_inst.mm_master_bfm_0.set_command_burst_size(1); tb.simulation_inst.mm_master_bfm_0.set_command_burst_count(1); tb.simulation_inst.mm_master_bfm_0.set_command_burst_size(8); tb.simulation_inst.mm_master_bfm_0.set_command_burst_count(8); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable, 1); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable, 2); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable, 3); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable, 4); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable, 5); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable, 6); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable, 7); tb.simulation_inst.mm_master_bfm_0.set_command_data(data, `INDEX_ZERO); tb.simulation_inst.mm_master_bfm_0.set_command_data($random(), 1); tb.simulation_inst.mm_master_bfm_0.set_command_data($random(), 2); tb.simulation_inst.mm_master_bfm_0.set_command_data($random(), 3); tb.simulation_inst.mm_master_bfm_0.set_command_data($random(), 4); tb.simulation_inst.mm_master_bfm_0.set_command_data($random(), 5); tb.simulation_inst.mm_master_bfm_0.set_command_data($random(), 6); tb.simulation_inst.mm_master_bfm_0.set_command_data($random(), 7); tb.simulation_inst.mm_master_bfm_0.push_command(); tb.simulation_inst.mm_master_bfm_1.set_command_request(request); tb.simulation_inst.mm_master_bfm_1.set_command_idle(idle, `INDEX_ZERO); tb.simulation_inst.mm_master_bfm_1.set_command_init_latency(init_latency); tb.simulation_inst.mm_master_bfm_1.set_command_address(addr); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable,`INDEX_ZERO); tb.simulation_inst.mm_master_bfm_1.set_command_burst_size(1); tb.simulation_inst.mm_master_bfm_1.set_command_burst_count(1); tb.simulation_inst.mm_master_bfm_1.set_command_burst_size(8); tb.simulation_inst.mm_master_bfm_1.set_command_burst_count(8); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable, 1); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable, 2); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable, 3); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable, 4); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable, 5); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable, 6); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable, 7); tb.simulation_inst.mm_master_bfm_1.set_command_data(data, `INDEX_ZERO); tb.simulation_inst.mm_master_bfm_1.set_command_data(1000*($random()), 1); tb.simulation_inst.mm_master_bfm_1.set_command_data($random(), 2); tb.simulation_inst.mm_master_bfm_1.set_command_data($random(), 3); tb.simulation_inst.mm_master_bfm_1.set_command_data($random(), 4); tb.simulation_inst.mm_master_bfm_1.set_command_data($random(), 5); tb.simulation_inst.mm_master_bfm_1.set_command_data($random(), 6); tb.simulation_inst.mm_master_bfm_1.set_command_data($random(), 7); //tb.simulation_inst.mm_master_bfm_1.push_command(); end else begin tb.simulation_inst.mm_master_bfm_0.set_command_request(request); tb.simulation_inst.mm_master_bfm_0.set_command_idle(idle, `INDEX_ZERO); tb.simulation_inst.mm_master_bfm_0.set_command_init_latency(init_latency); tb.simulation_inst.mm_master_bfm_0.set_command_address(addr); tb.simulation_inst.mm_master_bfm_0.set_command_byte_enable(byte_enable,`INDEX_ZERO); tb.simulation_inst.mm_master_bfm_0.set_command_burst_size(1); tb.simulation_inst.mm_master_bfm_0.set_command_burst_count(1); tb.simulation_inst.mm_master_bfm_0.set_command_data(0, 0); //tb.simulation_inst.mm_master_bfm_0.push_command(); tb.simulation_inst.mm_master_bfm_1.set_command_request(request); tb.simulation_inst.mm_master_bfm_1.set_command_idle(idle, `INDEX_ZERO); tb.simulation_inst.mm_master_bfm_1.set_command_init_latency(init_latency); tb.simulation_inst.mm_master_bfm_1.set_command_address(addr); tb.simulation_inst.mm_master_bfm_1.set_command_byte_enable(byte_enable,`INDEX_ZERO); tb.simulation_inst.mm_master_bfm_1.set_command_burst_size(1); tb.simulation_inst.mm_master_bfm_1.set_command_burst_count(1); tb.simulation_inst.mm_master_bfm_1.set_command_data(0, 0); tb.simulation_inst.mm_master_bfm_1.push_command(); end end endtask- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've very little experience with Verilog/SystemVerilog, so cannot provide much help in this area.
What happens if you write this as two separate tasks, i.e., task master1_set_and_push_command and task master2_set_and_push_command? This would result in the two BFMs being accessed from different tasks ... it would also result in unique objects/variables being passed to the BFMs, rather than common variables as you are using now ... though push_command() should copy everything allowing you to reuse those same variables in a subsequent call. Cheers, Dave- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tried to make 2 separate tasks with their own variables, but nothing positive happened. When I turn off time outs with tb.simulation_inst.mm_master_bfm_0.set_command_timeout(0); simulation does not crash anymore, but read task still does not work. Still searching for a solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Still searching for a solution. --- Quote End --- Create a service request with Altera directly, and upload your code (a simplified case). Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, Dave, I solved this problem. I cleaned my simulation project, generated everything once again and added to my read task these two lines:
wait(tb.simulation_inst.mm_master_bfm_0.signal_response_complete); tb.simulation_inst.mm_master_bfm_0.pop_response(); Now everything runs as expected :)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I solved this problem. I cleaned my simulation project, generated everything once again and added to my read task these two lines: wait(tb.simulation_inst.mm_master_bfm_0.signal_response_complete); tb.simulation_inst.mm_master_bfm_0.pop_response(); Now everything runs as expected :) --- Quote End --- Great! The error sounded like it was due to an object being reused before the underlying library was finished with it, so this wait makes sense. Thanks for posting your solution. Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, I used this code in my test program (in test program i used standart altera_avalon_mm_master_bfm and altera_avalon_mm_slave_bfm submodels), but i have a trouble with using read task.
--- Quote Start ---
// ============================================================
// Tasks
// ============================================================
//
// Avalon-MM single-transaction read and write procedures.
//
// ------------------------------------------------------------
task avalon_write (
// ------------------------------------------------------------
input addr,
input data
);
begin
// Construct the BFM request
`BFM.set_command_request(REQ_WRITE);
`BFM.set_command_idle(0, 0);
`BFM.set_command_init_latency(0);
`BFM.set_command_address(addr);
`BFM.set_command_byte_enable('1,0);
`BFM.set_command_data(data, 0);
// Queue the command
`BFM.push_command();
// Wait until the transaction has completed
while (`BFM.get_response_queue_size() != 1)
@(posedge clk);
// Dequeue the response and discard
`BFM.pop_response();
end
endtask
// ------------------------------------------------------------
task avalon_read (
// ------------------------------------------------------------
input addr,
output data
);
begin
// Construct the BFM request
`BFM.set_command_request(REQ_READ);
`BFM.set_command_idle(0, 0);
`BFM.set_command_init_latency(0);
`BFM.set_command_address(addr);
`BFM.set_command_byte_enable('1,0);
`BFM.set_command_data(0, 0);
// Queue the command
`BFM.push_command();
// Wait until the transaction has completed
while (`BFM.get_response_queue_size() != 1)
@(posedge clk);
// Dequeue the response and return the data
`BFM.pop_response();
data = `BFM.get_response_data(0);
end
endtask
Cheers, Dave --- Quote End --- When i use write task address and data proceed from Master to Slave and it can be seen in diagrams in ModelSim. But when i use read task Slave component didn't form readdata in response to adress from Master. I added in read task this code
`SL.set_response_request(REQ_READ);
`SL.set_response_latency(0,0);
`SL.set_response_data('h1234567,0);
`SL.set_interface_wait_time(0,0);
`SL.push_response();
but nothing changed, readdata signal is unknown. What am I doing wrong?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- What am I doing wrong? --- Quote End --- I'm not sure. I have not used the Slave BFMs, so I do not have an example that I can compare your code to. I'd recommend starting with working code from an Altera example, and then modifying it to suit your needs until you track the error down. My guess is that you have not initialized the model correctly. The above Master BFM tests only work correctly because earlier in the main body of the code the Master BFM was initialized. Cheers, Dave
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Dave,
I'm having problems setting up my Modelsim to simulate a Qsys project. My issue is basically my testbench doesn't appear to be controlling the BFM master. I used the avalon_write and avalon_read tasks, but i can't see any bus activity from the Avalon bus. Anyway, I found this thread and tried following your tutorial to try to understand how the testbench controls the BFM master, but i'm also running into issues. From your tutorial, section 4.5.2 Avalon-MM Master BFM, i can run upto the "com" command with no issues. But when i run this: vlog -sv $TUTORIAL/hdl/qsys_system/test/qsys_system_bfm_master_tb.sv -L qsys_system_bfm_master I get these errors: # ** Error: (vlog-19) Failed to access library 'qsys_system_bfm_master' at "qsys_system_bfm_master".# ** Error: h:/temp/altera_jtag_to_avalon_mm_tutorial/hdl/qsys_system/test/qsys_system_bfm_master_tb.sv(48): Could not find the package (verbosity_pkg). Design read will continue, but expect a cascade of errors after this failure. Furthermore if you experience a vopt-7 error immediately before this error then please check the package names or the library search paths on the command line.# ** Error: h:/temp/altera_jtag_to_avalon_mm_tutorial/hdl/qsys_system/test/qsys_system_bfm_master_tb.sv(49): Could not find the package (avalon_mm_pkg). Design read will continue, but expect a cascade of errors after this failure. Furthermore if you experience a vopt-7 error immediately before this error then please check the package names or the library search paths on the command line.# C:/altera/13.1/modelsim_ae/win32aloem/vlog failed. Any suggestion? I'm using Quartus 64 bit version 13.1.0 and Modelsim AE 10.1d. Thanks, Joel![](/skins/images/7B0AB6865064EAE32B30EC9A4E94B48A/responsive_peak/images/icon_anonymous_message.png)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page