|
Message
From: cvs at opencores.org<cvs@o...>
Date: Tue Mar 18 12:38:57 CET 2008
Subject: [cvs-checkins] MODIFIED: jop ...
Date: 00/08/03 18:12:38 Modified: jop/vhdl/simpcon sc_arbiter_tdma.vhd Log: First real functional version Revision Changes Path 1.4 jop/vhdl/simpcon/sc_arbiter_tdma.vhd http://www.opencores.org/cvsweb.shtml/jop/vhdl/simpcon/sc_arbiter_tdma.vhd.diff?r1=1.3&r2=1.4 (In the diff below, changes in quantity of whitespace are not shown.) Index: sc_arbiter_tdma.vhd =================================================================== RCS file: /cvsroot/9914pich/jop/vhdl/simpcon/sc_arbiter_tdma.vhd,v retrieving revision 1.3 retrieving revision 1.4 diff -u -b -r1.3 -r1.4 --- sc_arbiter_tdma.vhd 5 Mar 2008 10:00:59 -0000 1.3 +++ sc_arbiter_tdma.vhd 18 Mar 2008 11:38:57 -0000 1.4 @@ -30,6 +30,17 @@ -- 150108: Quasi Round Robin Arbiter -- added sync signal to arbiter -- 160108: First tests running with new Round Robin Arbiter -- 190208: Development of TDMA Arbiter +-- 130308: * Renaming of this_state to mode, follow_state to next_mode +-- * counter dependencies moved from FSM to slot generation +-- * changed set to 2 bits +-- * changed serv to servR and servW +-- * added signal pipelined +-- 140308: Working version + +-- TODO: - Add atomic for Wolfgang +-- - full pipelined version +-- - add period and time slots from software using RAM + library ieee; @@ -56,7 +67,7 @@ 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; @@ -65,8 +76,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 @@ -78,17 +94,17 @@ -- 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; @@ -103,52 +119,33 @@ -- test numbers -period <= 600; -cpu_time(0) <= 200; -cpu_time(1) <= 400; -cpu_time(2) <= 599; +period <= 300; +cpu_time(0) <= 100; +cpu_time(1) <= 200; +cpu_time(2) <= 299;
-- Generates the input register and saves incoming data for each master
gen_register: for i in 0 to cpu_cnt-1 generate
- process(clk)
+ 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
if reset = '1' then
@@ -161,108 +158,105 @@
end if;
end process;
--- A time slot is assigned for each CPU
-
+-- A time slot is assigned to each CPU
process(counter, cpu_time)
begin
for j in 0 to cpu_cnt-1 loop
slot(j) <= '0';
end loop;
- if (counter > -1) and (counter < cpu_time(0)) then
+ if (counter > -1) and (counter < cpu_time(0)-3) then -- from 0 to 96
slot(0) <= '1';
- elsif (counter > cpu_time(0)-1) and (counter < cpu_time(1)) then
+ elsif (counter > cpu_time(0)-1) and (counter < cpu_time(1)-3) then -- from 100 to 196
slot(1) <= '1';
- else
+ elsif (counter > cpu_time(1)-1) and (counter < cpu_time(2)-2) then -- from 200 to 296
slot(2) <= '1';
end if;
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, slot, counter, cpu_time)
+ process(state, mode, slot, counter, 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) and (slot(i) = '1') then
- -- pipelined access
- if (mem_in.rdy_cnt = 1) and (arb_out(i).rd = '1') and (counter < cpu_time(i)-4) 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 (slot(i) = '1') and (counter < cpu_time(i)-4)) 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 (slot(i) = '1') and (counter < cpu_time(i)-4)) 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
- 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 =>
- if ((mem_in.rdy_cnt = 0) and (slot(i) = '1') and (counter < cpu_time(i)-4)) 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 (slot(i) = '1') and (counter < cpu_time(i)-4)) 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 =>
@@ -287,7 +281,7 @@
-- The arbiter output
-process (arb_out, reg_in, next_state)
+process (arb_out, reg_out, next_state)
begin
mem_out.rd <= '0';
@@ -297,18 +291,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;
@@ -316,36 +310,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;
@@ -355,34 +356,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 =>
- --- Here is happens something thats wrong!!!!
- 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 =>
|
 |