FPGARelated.com
Forums

need help with vhdl code in custom IP

Started by Unknown March 21, 2006
Hi,
I'm trying to do multiply-and-accumulate (MAC) in a custom IP created
by Create/Import IP peripherals in XPS. Xilinx provides basic
read/write functions with the user_logic vhdl code. I removed the code
for reg2 and reg3 in these two processes. I then added MUL_AND_ACCUM
process. I'm not a vhdl programmer, so I'm having difficulty with this
simple piece of logic. All I'm trying to do is

mul (reg3) = num1 (reg0) * num2 (reg1);
accum (reg2) = accum (reg2) + mul (reg3);

I wrote a process:

  MUL_AND_ACCUM_PROC : process( Bus2IP_Clk) is
  begin

    if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
      if Bus2IP_Reset = '1' then
        slv_reg2 <= (others => '0');
        slv_reg3 <= (others => '0');
      else
   	if slv_reg_write_select = "0010" then
		slv_reg2 <= Bus2IP_Data(0 to 31);
   	else
		slv_reg3 <= slv_reg0 * slv_Reg1;
		slv_reg2 <= slv_reg2 + slv_reg3;
   	end if;
      end if;
    end if;
  end process MUL_AND_ACCUM_PROC;

I suppose when I write a 0 to slv_reg2, it'll initialize slv_reg2 to 0.
Once it's initialized, I can simply write to slv_reg0 and slv_reg1, and
obtain the accumulated value in slv_reg2. But when I wrote a test
program in C to test this IP:

FPGA_MAC_mWriteReg(XPAR_FPGA_MAC_0_BASEADDR,0x8,3);

FPGA_MAC_mWriteReg(XPAR_FPGA_MAC_0_BASEADDR,0,8);
a = FPGA_MAC_mReadReg(XPAR_FPGA_MAC_0_BASEADDR,0);
printf("a: %d\n",a);

FPGA_MAC_mWriteReg(XPAR_FPGA_MAC_0_BASEADDR,0x4,4);
b = FPGA_MAC_mReadReg(XPAR_FPGA_MAC_0_BASEADDR,0x4);
printf("b: %d\n",b);

product = FPGA_MAC_mReadReg(XPAR_FPGA_MAC_0_BASEADDR,0xc);
printf("product = : %d\n",product);
output = FPGA_MAC_mReadReg(XPAR_FPGA_MAC_0_BASEADDR,0x8);
printf("output = : %d\n",output);

I have the following output:
a: 8
b: 4
product = : 1657088
output = : 32
a: 2
b: 5
product = : 12544852
output = : 10

It seems product and output are reversed somehow. It just doesn't work
as I expected. I can't figure out what's wrong with my code. I have
very little knowledge of vhdl. Can anyone point it out to me? The
following shows the read/write processes. Thanks.

  SLAVE_REG_WRITE_PROC : process( Bus2IP_Clk ) is
  begin

    if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
      if Bus2IP_Reset = '1' then
        slv_reg0 <= (others => '0');
        slv_reg1 <= (others => '0');
      else
        case slv_reg_write_select is
          when "1000" => slv_reg0 <= Bus2IP_Data(0 to 31);
          when "0100" => slv_reg1 <= Bus2IP_Data(0 to 31);
          when others => null;
        end case;
      end if;
    end if;

  end process SLAVE_REG_WRITE_PROC;

  -- implement slave model register read mux
  SLAVE_REG_READ_PROC : process( slv_reg_read_select, slv_reg0,
slv_reg1, slv_reg2, slv_reg3 ) is
  begin

    case slv_reg_read_select is
      when "1000" => slv_ip2bus_data <= slv_reg0;
      when "0100" => slv_ip2bus_data <= slv_reg1;
      when "0010" => slv_ip2bus_data <= slv_reg2;
      when "0001" => slv_ip2bus_data <= slv_reg3;
      when others => slv_ip2bus_data <= (others => '0');
    end case;

  end process SLAVE_REG_READ_PROC;