Forum Discussion

TwoBit's avatar
TwoBit
Icon for New Contributor rankNew Contributor
6 years ago

BFM MM-Master Help for custom IP

Hi,

I have made a module that includes two FIFOs (taken from the IP catalog and set up by selecting options from the Wizard box.) There are a few registers made to be used for testing and in place of the NIOS processor and an external memory device that will be used later for data exchange. I'm sure my HDL is wrong, but since it compiles without errors, testing it with a BFM is what I'm told you're supposed to do to verify a custom IP. Here's what I'm trying to do and where I'm at.

The goal:

For the Read FIFO - a register (but it would be NIOS data in the future) writes to the read FIFO, another register (external memory later) will read in the output of the read FIFO.

For the Write FIFO: external memory (another register) will write to this FIFO and that FIFO's output will be displayed on the software output (or in another register currently)

I'm trying to test this module with a MM Master BFM since my module is a slave. I've built my project in Qsys - a clock, a reset, a MM Master BFM, and my custom component. This generated a .qip file successfully. Now I don't know what to do. Do I add this .qip to my Quartus project? I've read that you can select to "generate a testbench." This gave me an error that "System has no exported interfaces." Do I have to have something to export to do test benching? I thought I could just have to FIFOs and see if the registers linked to them were getting the right data in and out from the FIFOs...?

Most of the links I've found for tutorials or help no longer work and I'm really stuck. Any help would be much appreciated.

module wrap1 (
   input logic 	csi_clk,
   input logic 	rsi_reset,
 
// avalon signals: 
   input logic		avs_s1_read, 		
   input logic 		avs_s1_write,
   input logic 		[31:0]avs_s1_writedata,	
   input logic 		[3:0]avs_s1_address,
   output logic 	[31:0]avs_s1_readdata	
);
 
// For easier reading:
   wire			clock, reset, read, write;
   wire 		[3:0]address;
 
// Assign wires:
   assign clock = 	csi_clk;
   assign reset = 	rsi_reset;
   assign read = 	avs_s1_read;
   assign write = 	avs_s1_write;
   assign address = 	avs_s1_address;
 
//Registers for testing module:
 
//Memory "reg" reads from FIFO (sw writes to this FIFO)
   reg [15:0]readFifoOutput;
 
   reg [31:0]readInfo = '0;		
   reg [31:0]extraReg;			
 
//Memory "reg" writes to FIFO (sw reads FIFO ("reg")
   reg [15:0]preloadFifo = 16'b0101010101010101;	
 
   reg [15:0]writeOutput;
 
//Do I need these or do the FIFO IPs from the Quartus library handle these flags?
   reg writeFlag = 0;
   reg readFlag = 0;
 
// Instantiate the readFifo (this was automatically generated since it came from the IP catalog, I just filled in some of the () that I thought made sense.)// A register reads from FIFO (sw writes to FIFO)
 
   rdFifo rdFifo1 (
	.data(readInfo),
	.rdclk(clock),
	.rdreq(readFlag),
	.wrclk(clock),
	.wrreq(writeFlag),
	.q(readFifoOutput),
	.rdempty(),
	.wrfull()
   );
 
// Instantiate the writeFifo (this was automatically generated since it came from the IP catalog, I just filled in some of the () that I thought made sense.)
// Software reads from FIFO and FIFO is loaded by a register (which will be memory later but registers for now for testing and starting off)
   wrFifo wrFifo1 (
	.data(preloadFifo),
	.rdclk(clock),
	.rdreq(readFlag),
	.wrclk(clock),
	.wrreq(writeFlag),
	.q(writeOutput),
	.rdempty(),
	.wrfull()
   );
 
// Trying to make this FIFO setup work
   always @ (posedge clock, negedge reset) begin
	if (!reset) begin
		readInfo <= 0;
	end
	
	// ReadFifo: memory register reads FIFO (software/register writes to FIFO):
	else if (write && address == 0) begin
		writeFlag = 1;
 
	//memory device/register
		readInfo <= avs_s1_writedata[15:0];	
	
	//testing the elseif statement: 
		extraReg <= readFifoOutput;
		extraReg [31:16] <= 0;
 
//Not sure I need to do this
		writeFlag = 0;			
	end
 
// WriteFifo: memory reg writes to FIFO (software/register reads FIFO output)
	else if (read && address == 0) begin
		readFlag = 1;
 
	//memory device/reg
		avs_s1_readdata[15:0] <= writeOutput;	
 
		readFlag = 0;
	end
   end
 
endmodule

Here's what my current top level looks like:

5 Replies

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    What you're missing here, I think, is that a BFM is only for simulation in a tool like the included ModelSim-Intel FPGA Edition (or full ModelSim). There is no reason to open up a Platform Designer (aka Qsys) test bench system in Quartus or manually instantiate a BFM in code.

    The easiest thing to do is create a Platform Design system with just your component in it by itself, exporting all the interfaces. Then select the "Generate Testbench" option (standard setting) you mention. This creates a test bench system design that automatically selects, configures, and connects the appropriate BFMs for testing your component (like you say, a master BFM to drive your slave component but also clock and reset BFMs as needed) including scripts for running a simulation in a simulation tool. You got the error you mentioned because you didn't have exported interfaces to connect to BFMs in the newly generated testbench system. It does create a new .qsys file, but this is really just for looking at how the testbench system is set up, not for generating or compiling in Quartus since it is not synthesizable.

    You can use the generated test bench program or write a test bench program to control the BFM(s) using the simple API documented in the verification IP user guide (https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_avalon_verification_ip.pdf).

    See this online training for details: https://www.intel.com/content/www/us/en/programmable/support/training/course/oaqsyssim.html

    #iwork4intel

  • TwoBit's avatar
    TwoBit
    Icon for New Contributor rankNew Contributor

    OK, thank you. I exported everything on my custom IP module and now have the test bench design made (I can see a new .qsys file made like you said), but I am still getting errors when I compile my quartus project. Do I even need to be able to compile my quartus project or is this test bench COMPLETELY separate from the project I made to design the custom IP module? My goal is to run ModelSim so that I can see how my custom module is behaving. If I need quartus to compile, do I add the testbench.v file to the project and set that as my new top-level?

    Or, do I just ignore my Quartus project now and startup ModelSim and try to run the testbench that was generated? I opened that first link but it wasn't very helpful to me yet as I am still learning how to get setup and it goes over commands and things that still beyond me right now. I had trouble opening the online training but I think that is my own computer issue so I will try it again later and go through the course.

    Thank you for your help! Any further tips are greatly appreciated.

  • sstrell's avatar
    sstrell
    Icon for Super Contributor rankSuper Contributor

    Like I said, a design with a BFM is not synthesizable so you can't compile it. It is for simulation only. The testbench and everything else generated by Platform Designer when you do "Generate Testbench" is for the simulation tool, not Quartus.

    #iwork4intel

  • TwoBit's avatar
    TwoBit
    Icon for New Contributor rankNew Contributor

    OK, I'll try to run it in modelsim next then. Thank you.