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 > Cvs-checkins > Message List > Message Post

    Message

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

    From: cvs at opencores.org<cvs@o...>
    Date: Thu Jul 24 14:46:58 CEST 2008
    Subject: [cvs-checkins] MODIFIED: jop ...
    Top
    Date: 00/08/07 24:14:46

    Modified: jop/vhdl/simpcon sc_arbiter_fair.vhd
    Log:
    added data_reg for each CPU in sc_fair_arbiter


    Revision Changes Path
    1.4 jop/vhdl/simpcon/sc_arbiter_fair.vhd

    http://www.opencores.org/cvsweb.shtml/jop/vhdl/simpcon/sc_arbiter_fair.vhd.diff?r1=1.3&r2=1.4

    (In the diff below, changes in quantity of whitespace are not shown.)

    Index: sc_arbiter_fair.vhd
    ===================================================================
    RCS file: /cvsroot/9914pich/jop/vhdl/simpcon/sc_arbiter_fair.vhd,v
    retrieving revision 1.3
    retrieving revision 1.4
    diff -u -b -r1.3 -r1.4
    --- sc_arbiter_fair.vhd 23 Apr 2008 14:15:02 -0000 1.3
    +++ sc_arbiter_fair.vhd 24 Jul 2008 12:46:58 -0000 1.4
    @@ -29,11 +29,11 @@
    -- 030707: Several bugs are fixed now. CMP with 3 running masters functions!
    -- 150108: Quasi Round Robin Arbiter -- added sync signal to arbiter
    -- 160108: First tests running with new Round Robin Arbiter
    +-- 250408: Renaming of this_state to mode, follow_state to next_mode, reg_in to reg_out
    +-- 240708: added data_reg for each CPU in arbiter

    -- Functioning: See description of SIES08 paper

    -
    -
    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    @@ -52,15 +52,13 @@
    arb_in : out arb_in_type(0 to cpu_cnt-1);
    mem_out : out sc_out_type;
    mem_in : in sc_in_type
    - --sync_in_array : in sync_in_array_type(0 to cpu_cnt-1);
    - --sync_out_array : in sync_out_array_type(0 to cpu_cnt-1)
    );
    end arbiter;


    architecture rtl of arbiter is

    --- signals for the input register of each master
    +-- stores the signals in a register of each master

    type reg_type is record
    rd : std_logic;
    @@ -69,8 +67,13 @@
    address : std_logic_vector(addr_bits-1 downto 0);
    end record;

    - type reg_array_type is array (0 to cpu_cnt-1) of reg_type;
    - signal reg_in : reg_array_type;
    + type reg_out_type is array (0 to cpu_cnt-1) of reg_type;
    + signal reg_out : reg_out_type;
    +
    +-- register to CPU for rd_data
    +
    + type reg_in_type is array (0 to cpu_cnt-1) of std_logic_vector(31 downto 0);
    + signal reg_in_rd_data : reg_in_type;

    -- one fsm for each CPU

    @@ -82,20 +85,22 @@

    -- one fsm for each serve

    - type serve_type is (idl, serv);
    + type serve_type is (idl, servR, servW);
    type serve_array is array (0 to cpu_cnt-1) of serve_type;
    - signal this_state : serve_array;
    - signal follow_state : serve_array;
    + signal mode : serve_array;
    + signal next_mode : serve_array;

    -- arbiter

    - type set_type is array (0 to cpu_cnt-1) of std_logic;
    + type set_type is array (0 to cpu_cnt-1) of std_logic_vector(1 downto 0);
    signal set : set_type;
    - signal waiting : set_type;
    - signal masterWaiting : std_logic;
    + type pipelined_type is array (0 to cpu_cnt-1) of std_logic;
    + signal pipelined : pipelined_type;

    -- counter
    signal counter : integer;
    + type slot_type is array (0 to cpu_cnt-1) of std_logic;
    + signal slot : slot_type; -- defines which CPU is on turn


    begin
    @@ -106,39 +111,21 @@
    process(clk, reset)
    begin
    if reset = '1' then
    - reg_in(i).rd <= '0'; - reg_in(i).wr <= '0'; - reg_in(i).wr_data <= (others => '0'); - reg_in(i).address <= (others => '0'); + reg_out(i).rd <= '0'; + reg_out(i).wr <= '0'; + reg_out(i).wr_data <= (others => '0'); + reg_out(i).address <= (others => '0'); elsif rising_edge(clk) then if arb_out(i).rd = '1' or arb_out(i).wr = '1' then - reg_in(i).rd <= arb_out(i).rd; - reg_in(i).wr <= arb_out(i).wr; - reg_in(i).address <= arb_out(i).address; - reg_in(i).wr_data <= arb_out(i).wr_data; + reg_out(i).rd <= arb_out(i).rd; + reg_out(i).wr <= arb_out(i).wr; + reg_out(i).address <= arb_out(i).address; + reg_out(i).wr_data <= arb_out(i).wr_data; end if; end if; end process; end generate; --- Register for masterWaiting -process(clk, reset) - begin - if reset = '1' then - masterWaiting <= '0'; - elsif rising_edge(clk) then - for i in 0 to cpu_cnt-1 loop - if waiting(i) = '1' then - masterWaiting <= '1'; - exit; - else - masterWaiting <= '0'; - end if; - end loop; - end if; - end process; - - -- Generate Counter process(clk, reset) begin @@ -148,16 +135,12 @@ counter <= counter + 1; for i in 0 to cpu_cnt-1 loop - if arb_out(i).atomic = '1' and counter = i then - counter <= counter; - exit; - else - if follow_state(i) = serv then + if next_mode(i) = servR or next_mode(i) = servW then if mem_in.rdy_cnt = 1 and arb_out(i).rd = '0' then if counter = cpu_cnt-1 then counter <= 0; else - counter <= counter + 1; + counter <= counter+1; end if; exit; else @@ -167,97 +150,105 @@ elsif counter = cpu_cnt-1 then counter <= 0; end if; - end if; end loop; end if; - end process; +end process; + +-- The slot is assigned depending on the counter +process(counter) + begin + for j in 0 to cpu_cnt-1 loop + if j = counter then + slot(j) <= '1'; + else + slot(j) <= '0'; + end if; + end loop; +end process; -- Generates next state of the FSM for each master gen_next_state: for i in 0 to cpu_cnt-1 generate - process(reset, state, arb_out, mem_in, this_state, reg_in, masterWaiting, counter) + process(state, mode, slot, mem_in, arb_out) begin next_state(i) <= state(i); - waiting(i) <= '0'; + pipelined(i) <= '0'; case state(i) is when idle => - -- checks if this CPU is on turn (pipelined access) - if this_state(i) = serv then - -- pipelined access - if mem_in.rdy_cnt = 1 and arb_out(i).rd = '1' then - next_state(i) <= read; + -- is CPU allowed to access + if (slot(i) = '1') then - elsif ((mem_in.rdy_cnt = 0) and (arb_out(i).rd = '1' or arb_out(i).wr = '1') and (counter = i)) then + -- pipelined read access + if (mode(i) = servR) and (mem_in.rdy_cnt = 1) and (arb_out(i).rd = '1') then + next_state(i) <= read; + pipelined(i) <= '1'; + elsif (mode(i) = servR) and (mem_in.rdy_cnt = 0) then if arb_out(i).rd = '1' then next_state(i) <= read; elsif arb_out(i).wr = '1' then next_state(i) <= write; end if; - -- all other kinds of rdy_cnt - else + elsif (mode(i) = servW) and (mem_in.rdy_cnt = 0) then if arb_out(i).rd = '1' then - next_state(i) <= waitingR; - waiting(i) <= '1'; + next_state(i) <= read; elsif arb_out(i).wr = '1' then - next_state(i) <= waitingW; - waiting(i) <= '1'; - end if; + next_state(i) <= write; end if; - -- CPU is not on turn (no pipelined access possible) - else - if ((mem_in.rdy_cnt = 0) and (arb_out(i).rd = '1' or arb_out(i).wr = '1') and (counter = i)) then - - -- master wants to access immediately + elsif (mode(i) = idl) and (mem_in.rdy_cnt = 0) then if arb_out(i).rd = '1' then next_state(i) <= read; elsif arb_out(i).wr = '1' then next_state(i) <= write; end if; - -- has to wait for rdy_cnt = 0 and counter = i - elsif (arb_out(i).rd = '1' or arb_out(i).wr = '1') then + -- all other kinds (can that happen at all?) + else if arb_out(i).rd = '1' then next_state(i) <= waitingR; - waiting(i) <= '1'; elsif arb_out(i).wr = '1' then next_state(i) <= waitingW; - waiting(i) <= '1'; - end if; end if; end if; + -- CPU is not allowed to access + else + if arb_out(i).rd = '1' then + next_state(i) <= waitingR; + elsif arb_out(i).wr = '1' then + next_state(i) <= waitingW; + end if; + end if; when read => next_state(i) <= idle; + if pipelined(i) = '1' then + pipelined(i) <= '1'; + end if; when write => next_state(i) <= idle; when waitingR => - -- Test of pipelining in arbiter!!!! - if ((mem_in.rdy_cnt = 0) and (counter = i)) then - -- if (((mem_in.rdy_cnt = 0) or (mem_in.rdy_cnt = 1)) and (counter = i)) then + if ((mem_in.rdy_cnt = 0) and (slot(i) = '1')) then next_state(i) <= sendR; else next_state(i) <= waitingR; - waiting(i) <= '1'; end if; when sendR => next_state(i) <= idle; when waitingW => - if ((mem_in.rdy_cnt = 0) and (counter = i)) then + if ((mem_in.rdy_cnt = 0) and (slot(i) = '1')) then next_state(i) <= sendW; else next_state(i) <= waitingW; - waiting(i) <= '1'; end if; when sendW => @@ -282,7 +273,7 @@ -- The arbiter output -process (arb_out, reg_in, next_state) +process (arb_out, reg_out, next_state) begin mem_out.rd <= '0'; @@ -292,18 +283,18 @@ mem_out.atomic <= '0'; for i in 0 to cpu_cnt-1 loop - set(i) <= '0'; + set(i) <= "00"; case next_state(i) is when idle => when read => - set(i) <= '1'; + set(i) <= "01"; mem_out.rd <= arb_out(i).rd; mem_out.address <= arb_out(i).address; when write => - set(i) <= '1'; + set(i) <= "10"; mem_out.wr <= arb_out(i).wr; mem_out.address <= arb_out(i).address; mem_out.wr_data <= arb_out(i).wr_data; @@ -311,36 +302,43 @@ when waitingR => when sendR => - set(i) <= '1'; - mem_out.rd <= reg_in(i).rd; - mem_out.address <= reg_in(i).address; + set(i) <= "01"; + mem_out.rd <= reg_out(i).rd; + mem_out.address <= reg_out(i).address; when waitingW => when sendW => - set(i) <= '1'; - mem_out.wr <= reg_in(i).wr; - mem_out.address <= reg_in(i).address; - mem_out.wr_data <= reg_in(i).wr_data; + set(i) <= "10"; + mem_out.wr <= reg_out(i).wr; + mem_out.address <= reg_out(i).address; + mem_out.wr_data <= reg_out(i).wr_data; end case; end loop; end process; --- generation of follow_state +-- generation of next_mode gen_serve: for i in 0 to cpu_cnt-1 generate - process(mem_in, set, this_state) + process(mem_in, set, mode) begin - case this_state(i) is + case mode(i) is when idl => - follow_state(i) <= idl; - if set(i) = '1' then - follow_state(i) <= serv; - end if; - when serv => - follow_state(i) <= serv; - if mem_in.rdy_cnt = 0 and set(i) = '0' then - follow_state(i) <= idl; + next_mode(i) <= idl; + if set(i) = "01" then + next_mode(i) <= servR; + elsif set(i) = "10" then + next_mode(i) <= servW; + end if; + when servR => + next_mode(i) <= servR; + if mem_in.rdy_cnt = 0 and set(i) = "00" then + next_mode(i) <= idl; + end if; + when servW => + next_mode(i) <= servW; + if mem_in.rdy_cnt = 0 and set(i) = "00" then + next_mode(i) <= idl; end if; end case; end process; @@ -350,33 +348,67 @@ process (clk, reset) begin if (reset = '1') then - this_state(i) <= idl; + mode(i) <= idl; elsif (rising_edge(clk)) then - this_state(i) <= follow_state(i); + mode(i) <= next_mode(i); + end if; + end process; +end generate; + + + +-- Registers rd_data for each CPU +gen_reg_in: for i in 0 to cpu_cnt-1 generate + process(clk, reset) + begin + if reset = '1' then + reg_in_rd_data(i) <= (others => '0'); + elsif rising_edge(clk) then + if mode(i) = servR then + if mem_in.rdy_cnt = 0 then + reg_in_rd_data(i) <= mem_in.rd_data; + elsif mem_in.rdy_cnt = 2 and pipelined(i) = '1' then + reg_in_rd_data(i) <= mem_in.rd_data; + end if; + end if; end if; end process; end generate; + + +-- Generates rdy_cnt and rd_data for all CPUs gen_rdy_cnt: for i in 0 to cpu_cnt-1 generate - process (mem_in, state, this_state) + process (mem_in, state, mode) begin + + arb_in(i).rd_data <= reg_in_rd_data(i); arb_in(i).rdy_cnt <= mem_in.rdy_cnt; - arb_in(i).rd_data <= mem_in.rd_data; case state(i) is when idle => - case this_state(i) is - when idl => + if (mode(i) = idl) then arb_in(i).rdy_cnt <= "00"; - when serv => - end case; + elsif (mode(i) = servR) and (mem_in.rdy_cnt = 0) then + arb_in(i).rd_data <= mem_in.rd_data; + end if; when read => + if (mode(i) = servR) then + if (mem_in.rdy_cnt = 0) then + arb_in(i).rd_data <= mem_in.rd_data; + elsif (mem_in.rdy_cnt = 2) and pipelined(i) = '1' then + arb_in(i).rd_data <= mem_in.rd_data; + end if; + end if; when write => when waitingR => arb_in(i).rdy_cnt <= "11"; + if mode(i) = servR then + arb_in(i).rd_data <= mem_in.rd_data; + end if; when sendR =>

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