LOGIN   :::   RECOVER PASS   :::   GET ACCOUNT    
Browse
  • Projects
  • Code (CVS)
  • Forums
  • News
  • Articles
  • Polls
  •  
    OpenCores
  • FAQ
  • CVS HowTo
  • Mission
  • Media
  • Tools
  • Advertise
  • Mirrors
  • Logos
  • Contact us
  • Job Opportunity
  •  
    Tools
  • Search
      
  • Download Cores (CVSGet)
  •  
    More
  • Wishbone
  • Perlilog
  • EDA tools
  • OpenTech CD
  •  
    Navigation: All forums > Cores > Message List > Message Post

    Message

    Reply | Reply all
    Date Prev | Date Next | Thread Prev | Thread Next Date Index | Thread Index

    From: Umair Siddiqui<umairsiddiqui84@g...>
    Date: Wed Sep 7 00:59:10 CEST 2005
    Subject: [oc] hpc-16: continued ack_i problems
    Top
    the bus controling issues
    are creating problems. The complete code of cpu along with documentation is
    posted on OpenCores.org as *HPC-16* project. cpu only supports single
    read/write cycles. Currently I just simulating the CPU on modelsim,
    not tested on cpu. All signal assignments are in zero time, no timing
    info in CPU RTL or RAM models. i.e no "after unit_time".
    this is my first cpu...please help
    ////////////////////////////////////////////
    --// this code of sync, i tried both archs,
    --// first one delays the "ack_sync" arrival
    --// second one donot delay the async arrival

    entity sync is
    port
    (
    d : in std_logic;
    clk : in std_logic;
    q : out std_logic
    );
    end sync;

    architecture Behavioral of sync is
    signal t : std_logic;
    begin
    process(clk)
    begin
    if rising_edge(CLK) then
    t <= d;
    q <= t;
    end if;
    end process;
    end Behavioral;

    architecture behave2 of sync is
    signal t : std_logic;
    begin
    process(clk , d)
    begin
    if d = '1' then
    t <= '1';
    q <= '1';
    elsif rising_edge(clk) then
    t <= '0';
    q <= t;
    end if;
    end process;
    end behave2;

    /////////////////////////////////////
    --// control unit code fragments to
    --// highlight suspicious code related to
    --// bus controlling

    entity con1 is
    port(
    CLK_I : in std_logic;
    RST_I : in std_logic;
    ACK_I : in std_logic;
    SEL_O : out std_logic_vector(1 downto 0);
    STB_O : out std_logic;
    CYC_O : out std_logic;
    WE_O : out std_logic;
    ir_high : in std_logic_vector(7 downto 0);
    ...
    -- ***************************************** --
    -- ** DAT_IO (not separate DAT_I & DAT_O) ** --
    -- ** and ADR_O are ports of datapath ** --
    -- ***************************************** --
    -- ** may be DAT_IO is creating all evil! ** --
    -- ***************************************** --
    );
    end con1;
    architecture rtl of con1 is
    signal rst_sync : std_logic;
    signal ack_sync : std_logic;
    signal intr_sync : std_logic;
    signal cur_state , nxt_state : state;
    signal cur_ic : ic;
    ...
    begin
    rsync : sync
    port map
    (
    d => RST_I, clk => CLK_I, q => rst_sync
    );

    async : sync
    port map
    (
    d => ACK_I, clk => CLK_I, q => ack_sync
    );
    --////////////////////////////////////////////////////////
    -- combinational predecoding
    decode:
    cur_ic <= ic_mov_rn_rm when ir_high = mov_rn_rm else
    ic_mov_sp_rm when ir_high = mov_sp_rm else
    ic_mov_rn_sp when ir_high = mov_rn_sp else
    ic_ld_rn_rb when ir_high = ld_rn_rb else
    ic_ld_rn_rb_disp when ir_high = ld_rn_rb_disp else
    ...
    ic_hlt when ir_high(7 downto 3) = hlt else ic_invalid; --///////////////////////////////////////////////////////////// -- main fsm------------- process(CLK_I, rst_sync) begin if rst_sync = '1' then cur_state <= reset; elsif rising_edge(CLK_I) then cur_state <= nxt_state; end if; end process; process(cur_state, cur_ic, ir_high(2 downto 0), ack_sync, rst_sync, <other signals>) begin -- defualt assigns to avoid latch SEL_O <= "00"; STB_O <= '0'; CYC_O <= '0'; WE_O <= '0'; <other asigns> -- **************************************************** -- ** note: no default assign for "nxt_state" -- ** should i add: "nxt_state <= reset" -- **************************************************** --////////////////////////////////////// case cur_state is --////////////////////////////////////// when reset => -- generate control signals to reset the Program Counter (pc) and FLAGS if rst_sync = '0' then nxt_state <= fetch0; else nxt_state <= reset; end if; --////////////////////////////////////// when fetch0 => -- assign pc contents to memory address reg(connected to address bus): mar <= pc -- increament pc by two: pc <= pc + 2 nxt_state <= fetch1; --/////////////////////////////////////// when fetch1 => -- start instruction fetch cycle SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; -- prepare instruction register (ir) for instruction loading ir_ce <= '1'; nxt_state <= fetch2; --/////////////////////////////////////// when fetch2 => if ack_sync = '1' then -- ********************************************************* -- -- ** instruction register should be loaded at this point ** -- -- ** otherwise control unit should stay in this state. ** -- -- ** this another reason for adding *sync* to ack_i ** -- -- ** (no need to add wait state circuit for SPARTAN 3 ** -- -- ** BRAMS) ** -- -- ** ?? is this a clean way ?? ** -- -- ********************************************************* -- -- ** any way stop the bus cycle, since we have recieved ** -- -- ** the *ack_sync* ** -- -- ********************************************************* -- -- ** another issue: ** -- -- ** in a "zero delay simulation", if stb_o controls the ** -- -- ** controls the chip-select of RAM, the "cs" of ram ** -- -- ** will be deasserted, resulting in immediate high-z on** -- -- ** data bus, in fact my whole simulation start running ** -- -- ** in delta time, if i remove the sync from ack_i! ** -- -- ********************************************************* -- -- ** note: for any read or write cycle, the cpu ** -- -- ** *does not wait* for ack_sync to become deasserted ** -- -- ** so in simulation, ack_sync generated for fetch2 ** -- -- ** is falsely reused for exec2. ** -- -- ** this would be obvious if use first arch of sync, ** -- -- ** in second arch you will observe a glitch at this ** -- -- ** time. ** -- -- ********************************************************* -- nxt_state <= exec0; else -- continue instruction fetch & prepare ir and stay in this state SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; I_CYC_O <= '1'; ir_ce <= '1'; nxt_state <= fetch2; end if; --/////////////////////////////////////// -- ** execution phase 0** -- when exec0 => -- ** based on current instruction type! ** -- case cur_ic is -- **************************************** -- -- ** several types of instructions, ** -- -- ** please consider *int* and *iret* ** -- -- ** interrupt call and return ** -- -- **************************************** -- -- ** interrupt call: int <4-bit integer>** -- -- ** FLAGS and then PC ** -- -- ** are pushed into stack, then PC ** -- -- ** is assigned {vector no. x 8} ** -- -- **************************************** -- -- ** interrupt ret: iret ** -- -- ** memory words are poped into PC and ** -- -- ** then into FLAGS ** -- -- **************************************** -- when ic_int => -- stack pointer is decrmented by two : sp = old sp - 2 -- mar is also assigned with this new value: mar = old sp - 2 -- "mem data reg for output" (mdro) which is connected to data bus -- is assigned zero extended FLAGS: mdro = flags nxt_state <= exec1; ---------------------------------------- when ic_iret => -- increament the sp by two: sp = old sp + 2 -- but assign mar old value: mar = old sp nxt_state <= exec1; ---------------------------------------- -- other instruction types ---------------------------------------- when ic_invalid => -- handle invalid instructions by throwing exception -- separate "state chain" to handle the issue nxt_state <= invalid0; ---------------------------------------------- end case; --/////////////////////////////////////// -- ** execution phase 1** -- when exec1 => case cur_ic is ---------------------------------------------- when ic_iret => -- read data word (PC) SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; -- prepare "mem data reg for input" (mdri) for data loading mdri_ce <= '1'; -- nxt_state <= exec2; ---------------------------------------------- when ic_int => -- assert the tri state control mdro_oe <= '1'; -- write data word (FLAGS) SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; -- nxt_state <= exec2; ---------------------------------------------- -- other instruction types ---------------------------------------------- -- ***************************************** -- when others => null; -- ***************************************** -- end case; --/////////////////////////////////////// -- ** execution phase 2** -- when exec2 => case cur_ic is when ic_int => if ack_sync = '1' then -- ***************************************** -- ** now we can start another bus cycle: -- ** prepare to push PC -- ***************************************** -- mar = old sp -2 -- sp = old sp - 2 -- mdro = pc nxt_state <= exec3; else --***************************************** --** otherwise FLAGS may not be written --** continue the write cycle and stay in this state --***************************************** mdro_oe <= '1'; -- try writing data word SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; -- nxt_state <= exec2; end if; ----------------------------------------- when ic_iret => if ack_sync = '1' then -- **************************************** -- ** mdri might be loaded with mem word, -- ** copy it to pc, prepare for another -- ** pop -- **************************************** -- pc = mdri -- sp = old sp + 2 -- mar = old sp -- nxt_state <= exec3; else -- continue reading data word SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; -- mdri_ce <= '1'; -- nxt_state <= exec2; end if; -------------------------------------------- -- other instruction type -------------------------------------------- when others => null; ------------------------------------------- --/////////////////////////////////////// when exec3 => case cur_ic is when ic_int => mdro_oe <= '1'; -- start writting PC (write bus cycle) SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; -- nxt_state <= exec4; ---------------------------------------------- when ic_iret => mdri_ce <= '1'; -- try reading FLAGS (read bus cycle) SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; -- nxt_state <= exec4; ---------------------------------------------- when others => null; ---------------------------------------------- end case; --/////////////////////////////////////// when exec4 => case cur_ic is ---------------------------------------------- when ic_int => if ack_sync = '1' then -- pc = ext(ir(3..0)) * 8 -- execution complete, poll the interrupt pin nxt_state <= int_chk; else mdro_oe <= '1'; -- continue writting PC SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; WE_O <= '1'; -- nxt_state <= exec4; end if; ---------------------------------------------- when ic_iret => if ack_sync = '1' then -- flags = mdri -- nxt_state <= int_chk; else mdri_ce <= '1'; -- try reading FLAGS SEL_O <= "11"; STB_O <= '1'; CYC_O <= '1'; -- nxt_state <= exec4; end if; ---------------------------------------------- when others => null; ---------------------------------------------- end case; --////////////////////////////////////// -- rest of states --///////////////////////////////////// end case; end process; end rtl; ///////////////////////////////////////////////////////////////////////////////////////////

     
    Copyright (c) 1999 OPENCORES.ORG. All rights reserved.