Adapting Wishbone Cores For Use With The Papilio And DesignLab

After a hiatus of about a year I’ve pulled out my Papilio One FPGA board and started working on my VHDL programming skills again. The majority of my previous efforts involved putting together Wishbone cores for the ZPUino softcore and I thought I’d pick up where I left off. However, since I last spent any time with the Papilio toolset the community has moved on to the DesignLab IDE.

DesignLab is a great piece of software, allowing for the graphical design of FPGAs using chips from the included library of circuits. It even allows you to create projects based upon the ZPUino and AVR8 softcores.

But what about all those cores I designed using the old toolset? After studying tutorials on the GadgetFactory site and considering the problem, I came up with a workflow that allows me to adapt my existing WishBone cores for use in DesignLab and thought I’d share it for anyone else who might want to do something similar.

In The Beginning…

For this example, I’ll update a basic WishBone core for use as a DesignLab library. The VHDL code is listed below. All it does is write a value to a register and read it back out.

--
--  Basic Wishbone Core
-- 
--  Version: 1.0
--
--  Copyright 2014 J. Consugar
-- 
--  This code is in the public domain.
--  
--  This core does nothing but write a value to a register and allow
--  it to be read back.
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.ALL;
use ieee.std_logic_misc.ALL;
use std.textio.all;

library work;
use work.zpu_config.all;
use work.zpupkg.all;
use work.zpuinopkg.all;

entity basic_wishbone is
  port (
    -- Wishbone signals.
    -- ZPUino has a 32 bit word size.
    wb_clk_i: in std_logic;     -- FPGA clock signal
    wb_rst_i: in std_logic;     -- reset signal
    wb_dat_o: out std_logic_vector(wordSize-1 downto 0);      -- data out signal
    wb_dat_i: in std_logic_vector(wordSize-1 downto 0);       -- data in signal
    wb_adr_i: in std_logic_vector(maxIObit downto minIObit);  -- read/write address
    wb_we_i:  in std_logic;     -- write enable
    wb_cyc_i: in std_logic;
    wb_stb_i: in std_logic;
    wb_ack_o: out std_logic;
    wb_inta_o:out std_logic;
  );
end entity basic_wishbone;

architecture behave of basic_wishbone is

  -- Register to hold value
  signal regigster0 : std_logic_vector(31 downto 0);

begin
  --
  -- Acknowledge all tranfers per the wishbone spec.
  --
  wb_ack_o <= wb_stb_i and wb_cyc_i; 
  
  -- 
  -- Tie interrupt to '0', we never interrupt. 
  --
  wb_inta_o <= '0';
  
  --
  -- Write data processing block.
  --
  process(wb_clk_i, wb_rst_i)
  begin
    if (wb_rst_i = '1') then
      --
      -- Reset signal.
      --
      register0 <= (others => '0');
    elsif (rising_edge(wb_clk_i)) then
      --
      -- On the rising edge of the clock...
      --
      if (wb_cyc_i='1' and wb_stb_i='1' and wb_we_i='1') then
        case wb_adr_i(4 downto 2) is
          when "000" =>
            -- 
            -- Store the value.
            --
            register0 <= wb_dat_i;
          when others =>
            --
            -- No-op.
            --
        end case;
      end if;
    end if;
  end process;
  
  --
  -- Load the output data when address is read.
  --
  process(wb_adr_i, register0)
  begin
    case wb_adr_i(4 downto 2) is
      when "000" =>
        -- 
        -- Store the value to be returned.
        --
        wb_dat_o(31 downto 0) <= (others => '0');
        wb_dat_o(31 downto 0) <= register0;
      when others =>
        wb_dat_o(31 downto 0) <= (others => '0');
    end case;
  end process; 
  
end behave;

Creating The Project

To start, open DesignLab and select Papilio : New DesignLab Library – Wishbone VHDL to create the project. Change the name to BasicWishbone and click OK to save it.

edit_library - Papilio DesignLab

In the edit_library tab, click sketchdir://Chip_Designer.xise to open the project in the Xilinx ISE Project Navigator.

ISE Project Navigator

Updating The VHDL

Once the ISE Project Navigator is open, expand Edit_Your_Chip_Design in the Hierarchy tree and double-click the BasicWishbone entry to view the created VHDL code.

Basic WishBone VHDL

In the VHDL entity block, remove the leds and buttons connections. In the architecture block remove the Wishbone_to_Registers component and all associated signals and registers. Once you’re done, the code will look like this:

--------------------------------------------------------------------------------
-- Copyright (c) 1995-2013 Xilinx, Inc.  All rights reserved.
--------------------------------------------------------------------------------
--   ____  ____ 
--  /   /\/   / 
-- /___/  \  /    Vendor: Xilinx 
-- \   \   \/     Version : 14.7
--  \   \         Application : 
--  /   /         Filename : xil_12112_30
-- /___/   /\     Timestamp : 09/23/2014 15:24:59
-- \   \  /  \ 
--  \___\/\___\ 
--
--Command: 
--Design Name: 
--

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.Vcomponents.ALL;

library DesignLab;
use DesignLab.ALL;

entity BasicWishbone is
  port ( 
    wishbone_in  : in    std_logic_vector (100 downto 0); 
    wishbone_out : out   std_logic_vector (100 downto 0);
			 
		--Put your external connections here
  );
end BasicWishbone;

architecture BEHAVIORAL of BasicWishbone is
	
	--Put your unique register names here

begin

end BEHAVIORAL;

The DesignLab WishBone interface passes all signals into and out of the core via arrays. To make the code easier to read, add the aliases defined below to the top of the architecture block so the slices of interest can be accessed using their original names.

  --
  -- Rather than deal with slices out of the wishbone arrays we'll define some
  -- aliases here that allow use of the original names.
  --
  alias wb_clk_i: std_logic is wishbone_in(61);     -- FPGA clock signal
  alias wb_rst_i: std_logic is wishbone_in(60);     -- reset signal
  alias wb_dat_i: std_logic_vector(31 downto 0) is wishbone_in(59 downto 28); -- data in signal
  alias wb_adr_i: std_logic_vector(26 downto 2) is wishbone_in(27 downto 3);  -- read/write address
  alias wb_we_i : std_logic is wishbone_in(2);      -- write enable
  alias wb_cyc_i: std_logic is wishbone_in(1);
  alias wb_stb_i: std_logic is wishbone_in(0);

  alias wb_dat_o: std_logic_vector(31 downto 0) is wishbone_out(33 downto 2); -- data out signal
  alias wb_ack_o: std_logic is wishbone_out(1);
  alias wb_inta_o:std_logic is wishbone_out(0);

Now it’s time to copy the WishBone code from the original core. For each block in the original core, copy the VHDL code to the Xilinx ISE project code. For this example, the result will look like the code below.

--------------------------------------------------------------------------------
-- Copyright (c) 1995-2013 Xilinx, Inc.  All rights reserved.
--------------------------------------------------------------------------------
--   ____  ____ 
--  /   /\/   / 
-- /___/  \  /    Vendor: Xilinx 
-- \   \   \/     Version : 14.7
--  \   \         Application : 
--  /   /         Filename : xil_12112_30
-- /___/   /\     Timestamp : 09/23/2014 15:24:59
-- \   \  /  \ 
--  \___\/\___\ 
--
--Command: 
--Design Name: 
--

library ieee;
use ieee.std_logic_1164.ALL;
use ieee.numeric_std.ALL;
library UNISIM;
use UNISIM.Vcomponents.ALL;

library DesignLab;
use DesignLab.ALL;

entity BasicWishbone is
  port ( 
    wishbone_in  : in    std_logic_vector (100 downto 0); 
    wishbone_out : out   std_logic_vector (100 downto 0)
			 
    -- Put your external connections here
  );
end BasicWishbone;

architecture BEHAVIORAL of BasicWishbone is
	
  -- Put your unique register names here
  --
  -- Rather than deal with slices out of the wishbone arrays we'll define some
  -- aliases here that allow use of the original names.
  --
  alias wb_clk_i: std_logic is wishbone_in(61);     -- FPGA clock signal
  alias wb_rst_i: std_logic is wishbone_in(60);     -- reset signal
  alias wb_dat_i: std_logic_vector(31 downto 0) is wishbone_in(59 downto 28); -- data in signal
  alias wb_adr_i: std_logic_vector(26 downto 2) is wishbone_in(27 downto 3);  -- read/write address
  alias wb_we_i : std_logic is wishbone_in(2);      -- write enable
  alias wb_cyc_i: std_logic is wishbone_in(1);
  alias wb_stb_i: std_logic is wishbone_in(0);

  alias wb_dat_o: std_logic_vector(31 downto 0) is wishbone_out(33 downto 2); -- data out signal
  alias wb_ack_o: std_logic is wishbone_out(1);
  alias wb_inta_o:std_logic is wishbone_out(0);
  
  --
  -- Simple register to hold contents of a Wishbone read/write.
  --
  signal register0: std_logic_vector(31 downto 0);
begin
  -- Begin the architecture code.
  --
  -- Acknowledge all tranfers per the wishbone spec.
  --
  wb_ack_o <= wb_stb_i and wb_cyc_i; 
  
  -- 
  -- Tie interrupt to '0', we never interrupt 
  --
  wb_inta_o <= '0';
    
  --
  -- Write register processing loop.
  --
  process(wb_clk_i, wb_rst_i)
  begin
    if (wb_rst_i = '1') then
      --
      -- Circuit reset.
      -- 
      register0 <= (others => '0');   -- Initialize register to all '0'
      
    elsif (rising_edge(wb_clk_i)) then
      --
      -- On the rising edge of the clock...
      --
      if (wb_cyc_i='1' and wb_stb_i='1' and wb_we_i='1') then
        -- 
        -- Decoded as a write signal.
        --
        case wb_adr_i(4 downto 2) is
          when "000" =>
            --
            -- Accessing register 000
            -- Save the written value.
            --
            register0 <= wb_dat_i;
          when others =>
        end case;
      end if;
    end if;
  end process;
  
  --
  -- Load the output data when address is read.
  --
  process(wb_adr_i, register0)
  begin
    case wb_adr_i(4 downto 2) is
      when "000" =>
        -- 
        -- Store the value to be returned.
        --
        wb_dat_o(31 downto 0) <= (others => '0');
        wb_dat_o(31 downto 0) <= register0;
      when others =>
        wb_dat_o(31 downto 0) <= (others => '0');
    end case;
  end process;  
end BEHAVIORAL;

Creating The Schematic Symbol

To create the schematic symbol, expand Edit_Your_Chip_Design in the Hierarchy tree, right-click on the BasicWishbone entry, and select Source Properties. When the Source Properties form is displayed, change the Source Library to work and click OK.

Source Properties Form

Expand the Design Utilities in the Processes tree, and double-click Create Schematic Symbol. The process will run for a bit and if all is successful you’ll get a green check.

Create Schematic Symbol - Green Check

To confirm the schematic symbol has been created properly, double-click Edit_Your_Chip_Design in the Hierarchy tree. When you get the Open Schematic File Errors form, select Ignore The Error as the Action, click Update Instances, and OK to close the form.

Open Schematic File Errors

The updated schematic symbol should be shown on the display. You can now go back to the DesignLab IDE and perform the remaining steps to finish putting together your library.

Advertisements

Comments are closed.

Tabula Candida

Doodles of a distracted historian

rtl-sdr.com

A blog about RTL-SDR (RTL2832) and cheap software defined radio

DuWayne's Place

Computers, Electronics, and Amateur Radio from KC3XM

QRP HomeBuilder - QRPHB -

Computers, Electronics, and Amateur Radio from KC3XM

Open Emitter

Computers, Electronics, and Amateur Radio from KC3XM

Ripples in the Ether

Emanations from Amateur Radio Station NT7S

m0xpd's 'Shack Nasties'

Computers, Electronics, and Amateur Radio from KC3XM

%d bloggers like this: