tree: cc47d1c8526c52bbd463eb4ec655d06e955a51f0 [path history] [tgz]
  1. fpu_test_add_sub/
  2. fpu_test_comp/
  3. fpu_test_div/
  4. fpu_test_f2i/
  5. fpu_test_fclass/
  6. fpu_test_fma/
  7. fpu_test_i2f/
  8. fpu_test_min_max/
  9. fpu_test_multiply/
  10. fpu_test_sign_inject/
  11. fpu_test_sqrt/
  12. io_ports_fpu_test/
  13. la_test2_fpu/
  14. dv_defs.h
  15. Makefile
  16. README.md
verilog/dv/README.md

User Project Example DV

The directory includes multiple tests for the FPU user-project example:

IO Ports Test

  • This test is meant to verify that we can configure the pads for the user project area. The firmware configures the lower 32 IO pads in the user space as outputs:

    	reg_mprj_io_0 	=  GPIO_MODE_USER_STD_OUTPUT;
    	reg_mprj_io_1 	=  GPIO_MODE_USER_STD_OUTPUT;
    	.....
    	reg_mprj_io_32 	=  GPIO_MODE_USER_STD_OUTPUT;
    
  • Then, the firmware applies the pad configuration by enabling the serial transfer on the shift register responsible for configuring the pads and waits until the transfer is done.

    	reg_mprj_xfer = 1;
    	while (reg_mprj_xfer == 1);
    
  • The testbench success criteria is that we can observe the fpu_result output value on the lower 32 I/O pads. This criteria is checked by the testbench through observing the values on the I/O pads as follows:

    	wait(mprj_io == 32'h00000003); //(in our case result was 0x00000003)
    
    
  • If the testbench fails, it will print a timeout message to the terminal.

Logic Analyzer Test

  • This test is meant to verify that we can use the logic analyzer to monitor and write signals in the user project from the management SoC. Firstly, the firmware configures the upper 16 of the first 32 GPIO pads as outputs from the managent SoC, applies the configuration by initiating the serial transfer on the shift register, and writes a value on the pads to indicate the end of pad configuration and the start of the test.

    	reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
    	reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
    	.....
    	reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT;
    
    	reg_mprj_xfer = 1;
    	while (reg_mprj_xfer == 1);
    
    	// Flag start of the test 
    	reg_mprj_datal = 0xAB600000;
    

    This is done to flag the start/success/end of the simulation by writing a certain value to the I/Os which is then checked by the testbench to know whether the test started/ended/succeeded. For example, the testbench checks on the value of the upper 16 of 32 I/Os, if it is equal to 16'hAB60, then we know that the test started.

    	wait(checkbits == 16'hAB60);
    	$display("LA Test started");
    
  • Then, the firmware configures the logic analyzer (LA) probes [31:0] as inputs to the user project example to send the address value, and configure the logic analyzer probes [63:32] as outputs from the management SoC (inputs to the user_proj_example) to set the data value to that particular address set earlier. This is done by writing to the LA probes enable registers. Note that the output enable is active low, while the input enable is active high. Every channel can be configured for input, output, or both independently.

    	reg_la0_oenb = reg_la0_iena = 0x00000000;    
    	reg_la1_oenb = reg_la1_iena = 0x00000000;    
    
  • In the user_proj_example RTL, the clock can either be supplied from the wb_clk_i or from the logic analyzer through bit [64]. Similarly, the reset signal can be supplied from the wb_rst_i or through LA[65]. The firmware configures the clk and reset LA probes as outputs from the management SoC by writing to the LA2 enable register.

    	reg_la2_oenb  = reg_la2_iena = 0xFFFFFFFC; 	// Configure LA[64] LA[65] as outputs from the cpu
    
  • Then, the firmware supplies both clock reset signals through LA2 data register. First, both are set to one. Then, reset is driven to zero and the clock is toggled for 6 clock cycles and it writes the values to the input csrs of fpu at each clock cycle. And then disable probs as inputs to read the result value.

    	reg_la2_data = 0x00000003;	// Write one to LA[64] and LA[65]
    	for (i=0; i<12; i=i+1) {   	// Toggle clk & de-assert reset
    		clk = !clk;               	
    		reg_la2_data = 0x00000000 | clk;
    		if(i==0)
            {reg_la0_data = 0x30000000;
            reg_la1_data = 0x00000001; }
    		...
    		...
    	}
    

    reg_la0_oenb = reg_la0_iena = 0xFFFFFFFF; // Disable probes reg_la1_oenb = reg_la1_iena = 0xFFFFFFFF; // Disable probes
  • The firmware then checks the result value equal to 0x00000003 and flags the success of the test by writing 0xAB461 to pads 16 to 31. The firmware reads the result value through the logic analyzer probes [31:0]

    	if (reg_la0_data == 0x00000003) {	     // Read current result value through LA
    		reg_mprj_datal = 0xAB610000; // Flag success of the test
    		break;
    	}
    

Wishbone Tests

  • This test is meant to verify that we can read and write to the fpu registers through the wishbone port. The firmware writes a value to the input csrs which are operands and operation conntrol csr that controls which fpu operation to perform. Then it waits untill the interrupt csr value becomes 1 which indicates the completion of fpu operation. After completion of fpu operation final thing is to read the result and exception csr values and check whether it is according to the expected result depending upon the operaton. The read and write transactions happen through the management SoC wishbone bus and are initiated by either writing or reading from the user project address on the wishbone bus. These tests starting from fpu_test prefix use the same approach but they target different sub modules of FPU i.e.

    • fpu_test_add_sub
    • ...
    • ...
    • fpu_test_sqrt
  • The defines which target the user project example csrs are defined in dv_defs.h