⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 6805.vhd

📁 USB v1.1 RTL and design specification
💻 VHD
📖 第 1 页 / 共 5 页
字号:
-----------------------------------------------------------------------------------
--  68HC05 microcontroller implementation
--  Ulrich Riedel
--  v1.0  2006.01.21  first version
-----------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;

entity fadd is               -- full adder stage, interface
  port(a    : in  std_logic;
       b    : in  std_logic;
       cin  : in  std_logic;
       s    : out std_logic;
       cout : out std_logic);
end entity fadd;

architecture behavior of fadd is  -- full adder stage, body
begin  -- circuits of fadd
  s <= a xor b xor cin after 1 ns;
  cout <= (a and b) or (a and cin) or (b and cin) after 1 ns;
end architecture behavior; -- fadd
-------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
entity add8 is             -- simple 8 bit ripple carry adder
  port(a    : in  std_logic_vector(7 downto 0);
       b    : in  std_logic_vector(7 downto 0);
       cin  : in  std_logic; 
       sum  : out std_logic_vector(7 downto 0);
       cout : out std_logic);
end entity add8;

architecture behavior of add8 is
  signal c : std_logic_vector(0 to 6); -- internal carry signals
  component fadd   -- duplicates entity port
  port(a    : in  std_logic;
       b    : in  std_logic;
       cin  : in  std_logic;
       s    : out std_logic;
       cout : out std_logic);
  end component fadd ;
begin
  a0:            fadd port map(a(0), b(0), cin, sum(0), c(0));
  stage: for I in 1 to 6 generate
             as: fadd port map(a(I), b(I), c(I-1) , sum(I), c(I));
         end generate stage;
  a31:           fadd port map(a(7), b(7), c(6) , sum(7), cout);
end architecture behavior;  -- add8

-------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;

entity add8c is          -- one stage of carry save adder for multiplier
  port(
    b       : in  std_logic;                     -- a multiplier bit
    a       : in  std_logic_vector(7 downto 0);  -- multiplicand
    sum_in  : in  std_logic_vector(7 downto 0);  -- sums from previous stage
    cin     : in  std_logic_vector(7 downto 0);  -- carrys from previous stage
    sum_out : out std_logic_vector(7 downto 0);  -- sums to next stage
    cout    : out std_logic_vector(7 downto 0)); -- carrys to next stage
end add8c;

architecture behavior of add8c is
  signal zero : std_logic_vector(7 downto 0) := x"00";
  signal aa   : std_logic_vector(7 downto 0) := x"00";
  component fadd
    port(a    : in  std_logic;
         b    : in  std_logic;
         cin  : in  std_logic;
         s    : out std_logic;
         cout : out std_logic);
  end component fadd;
begin
  aa <= a when b = '1' else zero after 1 ns;
  stage: for I in 0 to 7 generate
    sta: fadd port map(aa(I), sum_in(I), cin(I) , sum_out(I), cout(I));
  end generate stage;  
end architecture behavior; -- add8csa

-------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;

entity mul8 is  -- 8 x 8 = 16 bit unsigned product multiplier
  port(a    : in  std_logic_vector(7 downto 0);  -- multiplicand
       b    : in  std_logic_vector(7 downto 0);  -- multiplier
       prod : out std_logic_vector(15 downto 0)); -- product
end mul8;

architecture behavior of mul8 is
  signal zero : std_logic_vector(7 downto 0) := x"00";
  signal nc1  : std_logic;
  type arr8 is array(0 to 7) of std_logic_vector(7 downto 0);
  signal s    : arr8; -- partial sums
  signal c    : arr8; -- partial carries
  signal ss   : arr8; -- shifted sums

  component add8c is
    port(b       : in  std_logic;
         a       : in  std_logic_vector(7 downto 0);
         sum_in  : in  std_logic_vector(7 downto 0);
         cin     : in  std_logic_vector(7 downto 0);
         sum_out : out std_logic_vector(7 downto 0);
         cout    : out std_logic_vector(7 downto 0));
  end component add8c;
  component add8
    port(a    : in  std_logic_vector(7 downto 0);
         b    : in  std_logic_vector(7 downto 0);
         cin  : in  std_logic; 
         sum  : out std_logic_vector(7 downto 0);
         cout : out std_logic);
  end component add8;
begin
  st0: add8c port map(b(0), a, zero , zero, s(0), c(0));  -- CSA stage
  ss(0) <= '0' & s(0)(7 downto 1) after 1 ns;
  prod(0) <= s(0)(0) after 1 ns;

  stage: for I in 1 to 7 generate
    st: add8c port map(b(I), a, ss(I-1) , c(I-1), s(I), c(I));  -- CSA stage
    ss(I) <= '0' & s(I)(7 downto 1) after 1 ns;
    prod(I) <= s(I)(0) after 1 ns;
  end generate stage;
  
  add: add8 port map(ss(7), c(7), '0' , prod(15 downto 8), nc1);  -- adder
end architecture behavior; -- mul8
-------------------------------------------------------------------------
-- begin of 6805
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.all;

ENTITY UR6805 IS
   PORT(
     clk     : in  std_logic;
     rst     : in  std_logic;
     irq     : in  std_logic;
     addr    : out std_logic_vector(15 downto 0);
     wr      : out std_logic;
     datain  : in  std_logic_vector(7 downto 0);
     state   : out std_logic_vector(3 downto 0);
     dataout : out std_logic_vector(7 downto 0)
   );
END UR6805;

ARCHITECTURE behavior OF UR6805 IS

  component mul8 port(
    a    : in  std_logic_vector(7 downto 0);
    b    : in  std_logic_vector(7 downto 0);
    prod : out std_logic_vector(15 downto 0)
    );
  end component mul8;
  
  constant CPUread  : std_logic := '1';
  constant CPUwrite : std_logic := '0';
  constant addrPC : std_logic_vector(2 downto 0) := "000";
  constant addrSP : std_logic_vector(2 downto 0) := "001";
  constant addrHX : std_logic_vector(2 downto 0) := "010";
  constant addrTM : std_logic_vector(2 downto 0) := "011";
  constant addrX2 : std_logic_vector(2 downto 0) := "100";
  constant addrS2 : std_logic_vector(2 downto 0) := "101";
  constant addrX1 : std_logic_vector(2 downto 0) := "110";
  constant addrS1 : std_logic_vector(2 downto 0) := "111";
  constant outA    : std_logic_vector(3 downto 0) := "0000";
  constant outH    : std_logic_vector(3 downto 0) := "0001";
  constant outX    : std_logic_vector(3 downto 0) := "0010";
  constant outSPL  : std_logic_vector(3 downto 0) := "0011";
  constant outSPH  : std_logic_vector(3 downto 0) := "0100";
  constant outPCL  : std_logic_vector(3 downto 0) := "0101";
  constant outPCH  : std_logic_vector(3 downto 0) := "0110";
  constant outTL   : std_logic_vector(3 downto 0) := "0111";
  constant outTH   : std_logic_vector(3 downto 0) := "1000";
  constant outHelp : std_logic_vector(3 downto 0) := "1001";
  constant outCode : std_logic_vector(3 downto 0) := "1010";

  type    masker is array (0 to 7) of std_logic_vector(7 downto 0);
  signal mask0  : masker;
  signal mask1  : masker;
  signal regA   : std_logic_vector(7 downto 0);
  signal regX   : std_logic_vector(7 downto 0);
  signal regSP  : std_logic_vector(15 downto 0);
  signal regPC  : std_logic_vector(15 downto 0);
  signal flagH  : std_logic;
  signal flagI  : std_logic;
  signal flagN  : std_logic;
  signal flagZ  : std_logic;
  signal flagC  : std_logic;
  signal help   : std_logic_vector(7 downto 0);
  signal temp   : std_logic_vector(15 downto 0);
  signal mainFSM : std_logic_vector(3 downto 0);
  signal addrMux : std_logic_vector(2 downto 0);
  signal dataMux : std_logic_vector(3 downto 0);
  signal opcode  : std_logic_vector(7 downto 0);
  signal prod     : std_logic_vector(15 downto 0);
  signal irq_d      : std_logic;
  signal irqRequest : std_logic;

  signal trace       : std_logic;
  signal trace_i     : std_logic;
  signal traceOpCode : std_logic_vector(7 downto 0);
  
begin

  mul: mul8 port map(
    a    => regA,
    b    => regX,
    prod => prod
  );
  
  addr <= regPC          when addrMux = addrPC else
          regSP          when addrMux = addrSP else
          x"00" & regX   when addrMux = addrHX else
          temp           when addrMux = addrTM else
          ((x"00" & regX) + temp) when addrMux = addrX2 else
          (regSP + temp) when addrMux = addrS2 else
          ((x"00" & regX) + (x"00" & temp(7 downto 0))) when addrMux = addrX1 else
          (regSP + (x"00" & temp(7 downto 0)));
  dataout <= regA               when dataMux = outA else
             regX               when dataMux = outH else
             regX               when dataMux = outX else
             regSP( 7 downto 0) when dataMux = outSPL else
             regSP(15 downto 8) when dataMux = outSPH else
             regPC( 7 downto 0) when dataMux = outPCL else
             regPC(15 downto 8) when dataMux = outPCH else
             temp ( 7 downto 0) when dataMux = outTL  else
             temp (15 downto 8) when dataMux = outTH  else
             help               when dataMux = outHelp else
             traceOpCode;

  state <= mainFSM;
  process(clk, rst)
    variable tres : std_logic_vector(7 downto 0);
    variable lres : std_logic_vector(15 downto 0);
  begin
    if rst = '0' then
      trace    <= '0';
      trace_i  <= '0';
      mask0(0) <= "11111110";
      mask0(1) <= "11111101";
      mask0(2) <= "11111011";
      mask0(3) <= "11110111";
      mask0(4) <= "11101111";
      mask0(5) <= "11011111";
      mask0(6) <= "10111111";
      mask0(7) <= "01111111";
      mask1(0) <= "00000001";
      mask1(1) <= "00000010";
      mask1(2) <= "00000100";
      mask1(3) <= "00001000";
      mask1(4) <= "00010000";
      mask1(5) <= "00100000";
      mask1(6) <= "01000000";
      mask1(7) <= "10000000";
      wr <= CPUread;
      flagH <= '0';
      flagI <= '1'; -- irq disabled
      flagN <= '0';
      flagZ <= '0';
      flagC <= '0';
      regA    <= x"00";
      regX    <= x"00";
      regSP   <= x"00FF";
      regPC   <= x"FFFE";
      temp    <= x"FFFE";
      help    <= x"00";
      dataMux <= outA;
      addrMux <= addrTM;
      irq_d   <= '1';
      irqRequest <= '0';
      mainFSM <= "0000";
    else
      if rising_edge(clk) then
        irq_d <= irq;
        if (irq <= '0') and (irq_d = '1') and (flagI = '0') then -- irq falling edge ?
          irqRequest <= '1';
        end if;
        case mainFSM is
          when "0000" => --############# reset fetch PCH from FFFE
            regPC(15 downto 8) <= datain;
            temp    <= temp + 1;
            mainFSM <= "0001";
          when "0001" => --############# reset fetch PCL from FFFF
            regPC(7 downto 0)  <= datain;
            addrMux <= addrPC;
            mainFSM <= "0010";
            
          when "0010" => --##################### fetch opcode, instruction cycle 1
            trace <= trace_i;
            if trace = '1' then
              opcode      <= x"83"; -- special SWI trace
              traceOpCode <= datain;
              addrMux     <= addrSP;
              mainFSM     <= "0011";              
            elsif irqRequest = '1' then
              opcode      <= x"83"; -- special SWI interrupt
              addrMux     <= addrSP;
              mainFSM     <= "0011";              
            else
              opcode <= datain;
              case datain is
                when x"82" =>  -- RTT return trace special propietary instruction
                  trace_i <= '1';  -- arm trace for next instruction
                  regSP   <= regSP + 1;
                  addrMux <= addrSP;
                  mainFSM <= "0011";
                when x"00" | x"02" | x"04" | x"06" | x"08" | x"0A" | x"0C" | x"0E" |   -- BRSET n,opr8a,rel

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -