Merge pull request #64 from antonblanchard/reformat-3

Reformat some more files
pull/67/head
Anton Blanchard 5 years ago committed by GitHub
commit 4df05e0598
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -6,55 +6,55 @@ library work;
use work.common.all;

entity cr_file is
port(
clk : in std_logic;
port(
clk : in std_logic;

d_in : in Decode2ToCrFileType;
d_out : out CrFileToDecode2Type;
d_in : in Decode2ToCrFileType;
d_out : out CrFileToDecode2Type;

w_in : in WritebackToCrFileType
);
w_in : in WritebackToCrFileType
);
end entity cr_file;

architecture behaviour of cr_file is
signal crs : std_ulogic_vector(31 downto 0) := (others => '0');
signal crs_updated : std_ulogic_vector(31 downto 0) := (others => '0');
signal crs : std_ulogic_vector(31 downto 0) := (others => '0');
signal crs_updated : std_ulogic_vector(31 downto 0) := (others => '0');
begin
cr_create_0: process(all)
variable hi, lo : integer := 0;
variable cr_tmp : std_ulogic_vector(31 downto 0) := (others => '0');
begin
cr_tmp := crs;

for i in 0 to 7 loop
if w_in.write_cr_mask(i) = '1' then
lo := i*4;
hi := lo + 3;
cr_tmp(hi downto lo) := w_in.write_cr_data(hi downto lo);
end if;
end loop;

crs_updated <= cr_tmp;
end process;

-- synchronous writes
cr_write_0: process(clk)
begin
if rising_edge(clk) then
if w_in.write_cr_enable = '1' then
report "Writing " & to_hstring(w_in.write_cr_data) & " to CR mask " & to_hstring(w_in.write_cr_mask);
end if;
crs <= crs_updated;
end if;
end process;

-- asynchronous reads
cr_read_0: process(all)
begin
-- just return the entire CR to make mfcrf easier for now
if d_in.read = '1' then
report "Reading CR " & to_hstring(crs_updated);
end if;
d_out.read_cr_data <= crs_updated;
end process;
cr_create_0: process(all)
variable hi, lo : integer := 0;
variable cr_tmp : std_ulogic_vector(31 downto 0) := (others => '0');
begin
cr_tmp := crs;

for i in 0 to 7 loop
if w_in.write_cr_mask(i) = '1' then
lo := i*4;
hi := lo + 3;
cr_tmp(hi downto lo) := w_in.write_cr_data(hi downto lo);
end if;
end loop;

crs_updated <= cr_tmp;
end process;

-- synchronous writes
cr_write_0: process(clk)
begin
if rising_edge(clk) then
if w_in.write_cr_enable = '1' then
report "Writing " & to_hstring(w_in.write_cr_data) & " to CR mask " & to_hstring(w_in.write_cr_mask);
end if;
crs <= crs_updated;
end if;
end process;

-- asynchronous reads
cr_read_0: process(all)
begin
-- just return the entire CR to make mfcrf easier for now
if d_in.read = '1' then
report "Reading CR " & to_hstring(crs_updated);
end if;
d_out.read_cr_data <= crs_updated;
end process;
end architecture behaviour;

@ -11,47 +11,47 @@ use work.ppc_fx_insns.all;
-- We handle rc form instructions here

entity execute2 is
port (
clk : in std_ulogic;
port (
clk : in std_ulogic;

e_in : in Execute1ToExecute2Type;
e_out : out Execute2ToWritebackType
);
e_in : in Execute1ToExecute2Type;
e_out : out Execute2ToWritebackType
);
end execute2;

architecture behave of execute2 is
signal r, rin : Execute2ToWritebackType;
signal r, rin : Execute2ToWritebackType;
begin
execute2_0: process(clk)
begin
if rising_edge(clk) then
r <= rin;
end if;
end process;

execute2_1: process(all)
variable v : Execute2ToWritebackType;
begin
v := rin;

v.valid := e_in.valid;
v.write_enable := e_in.write_enable;
v.write_reg := e_in.write_reg;
v.write_data := e_in.write_data;
v.write_cr_enable := e_in.write_cr_enable;
v.write_cr_mask := e_in.write_cr_mask;
v.write_cr_data := e_in.write_cr_data;

if e_in.valid = '1' and e_in.rc = '1' then
v.write_cr_enable := '1';
v.write_cr_mask := num_to_fxm(0);
v.write_cr_data := ppc_cmpi('1', e_in.write_data, x"0000") & x"0000000";
end if;

-- Update registers
rin <= v;

-- Update outputs
e_out <= r;
end process;
execute2_0: process(clk)
begin
if rising_edge(clk) then
r <= rin;
end if;
end process;

execute2_1: process(all)
variable v : Execute2ToWritebackType;
begin
v := rin;

v.valid := e_in.valid;
v.write_enable := e_in.write_enable;
v.write_reg := e_in.write_reg;
v.write_data := e_in.write_data;
v.write_cr_enable := e_in.write_cr_enable;
v.write_cr_mask := e_in.write_cr_mask;
v.write_cr_data := e_in.write_cr_data;

if e_in.valid = '1' and e_in.rc = '1' then
v.write_cr_enable := '1';
v.write_cr_mask := num_to_fxm(0);
v.write_cr_data := ppc_cmpi('1', e_in.write_data, x"0000") & x"0000000";
end if;

-- Update registers
rin <= v;

-- Update outputs
e_out <= r;
end process;
end;

@ -6,33 +6,33 @@ library work;
use work.glibc_random_helpers.all;

package glibc_random is
function pseudorand(a: integer) return std_ulogic_vector;
function pseudorand1 return std_ulogic;
function pseudorand(a: integer) return std_ulogic_vector;
function pseudorand1 return std_ulogic;
end package glibc_random;

package body glibc_random is
function pseudorand(a: integer) return std_ulogic_vector is
variable tmp1, tmp2, tmp3, tmp4: std_ulogic_vector(31 downto 0);
variable ret: std_ulogic_vector(63 downto 0);
begin
tmp1 := std_ulogic_vector(to_unsigned(random, 32));
tmp2 := std_ulogic_vector(to_unsigned(random, 32));
if a <= 32 then
ret := tmp1 & tmp2;
else
tmp3 := std_ulogic_vector(to_unsigned(random, 32));
tmp4 := std_ulogic_vector(to_unsigned(random, 32));
function pseudorand(a: integer) return std_ulogic_vector is
variable tmp1, tmp2, tmp3, tmp4: std_ulogic_vector(31 downto 0);
variable ret: std_ulogic_vector(63 downto 0);
begin
tmp1 := std_ulogic_vector(to_unsigned(random, 32));
tmp2 := std_ulogic_vector(to_unsigned(random, 32));
if a <= 32 then
ret := tmp1 & tmp2;
else
tmp3 := std_ulogic_vector(to_unsigned(random, 32));
tmp4 := std_ulogic_vector(to_unsigned(random, 32));

ret := tmp1(15 downto 0) & tmp2(15 downto 0) & tmp3(15 downto 0) & tmp4(15 downto 0);
end if;
ret := tmp1(15 downto 0) & tmp2(15 downto 0) & tmp3(15 downto 0) & tmp4(15 downto 0);
end if;

return ret((a-1) downto 0);
end;
return ret((a-1) downto 0);
end;

function pseudorand1 return std_ulogic is
variable tmp: std_ulogic_vector(31 downto 0);
begin
tmp := std_ulogic_vector(to_unsigned(random, 32));
return tmp(0);
end;
function pseudorand1 return std_ulogic is
variable tmp: std_ulogic_vector(31 downto 0);
begin
tmp := std_ulogic_vector(to_unsigned(random, 32));
return tmp(0);
end;
end package body glibc_random;

@ -1,19 +1,19 @@
package glibc_random_helpers is
procedure srand (v : integer);
attribute foreign of srand : procedure is "VHPIDIRECT srand";
procedure srand (v : integer);
attribute foreign of srand : procedure is "VHPIDIRECT srand";

function random return integer;
attribute foreign of random : function is "VHPIDIRECT random";
function random return integer;
attribute foreign of random : function is "VHPIDIRECT random";
end glibc_random_helpers;

package body glibc_random_helpers is
procedure srand (v : integer) is
begin
assert false severity failure;
end srand;
procedure srand (v : integer) is
begin
assert false severity failure;
end srand;

function random return integer is
begin
assert false severity failure;
end random;
function random return integer is
begin
assert false severity failure;
end random;
end glibc_random_helpers;

@ -12,252 +12,252 @@ entity multiply_tb is
end multiply_tb;

architecture behave of multiply_tb is
signal clk : std_ulogic;
constant clk_period : time := 10 ns;
signal clk : std_ulogic;
constant clk_period : time := 10 ns;

constant pipeline_depth: integer := 4;
constant pipeline_depth : integer := 4;

signal m1 : Decode2ToMultiplyType;
signal m2 : MultiplyToWritebackType;
signal m1 : Decode2ToMultiplyType;
signal m2 : MultiplyToWritebackType;
begin
multiply_0: entity work.multiply
generic map (PIPELINE_DEPTH => pipeline_depth)
port map (clk => clk, m_in => m1, m_out => m2);
multiply_0: entity work.multiply
generic map (PIPELINE_DEPTH => pipeline_depth)
port map (clk => clk, m_in => m1, m_out => m2);

clk_process: process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;
clk_process: process
begin
clk <= '0';
wait for clk_period/2;
clk <= '1';
wait for clk_period/2;
end process;

stim_process: process
variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
variable si: std_ulogic_vector(15 downto 0);
begin
wait for clk_period;
stim_process: process
variable ra, rb, rt, behave_rt: std_ulogic_vector(63 downto 0);
variable si: std_ulogic_vector(15 downto 0);
begin
wait for clk_period;

m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;
m1.write_reg <= "10001";
m1.data1 <= '0' & x"0000000000001000";
m1.data2 <= '0' & x"0000000000001111";
m1.rc <= '0';
m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;
m1.write_reg <= "10001";
m1.data1 <= '0' & x"0000000000001000";
m1.data2 <= '0' & x"0000000000001111";
m1.rc <= '0';

wait for clk_period;
assert m2.valid = '0';
wait for clk_period;
assert m2.valid = '0';

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period;
assert m2.valid = '0';
wait for clk_period;
assert m2.valid = '0';

wait for clk_period;
assert m2.valid = '0';
wait for clk_period;
assert m2.valid = '0';

wait for clk_period;
assert m2.valid = '1';
assert m2.write_reg_enable = '1';
assert m2.write_reg_nr = "10001";
assert m2.write_reg_data = x"0000000001111000";
assert m2.write_cr_enable = '0';
wait for clk_period;
assert m2.valid = '1';
assert m2.write_reg_enable = '1';
assert m2.write_reg_nr = "10001";
assert m2.write_reg_data = x"0000000001111000";
assert m2.write_cr_enable = '0';

wait for clk_period;
assert m2.valid = '0';
wait for clk_period;
assert m2.valid = '0';

m1.valid <= '1';
m1.rc <= '1';
m1.valid <= '1';
m1.rc <= '1';

wait for clk_period;
assert m2.valid = '0';
wait for clk_period;
assert m2.valid = '0';

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
assert m2.valid = '1';
assert m2.write_reg_enable = '1';
assert m2.write_reg_nr = "10001";
assert m2.write_reg_data = x"0000000001111000";
assert m2.write_cr_enable = '1';
assert m2.write_cr_data = x"40000000";
wait for clk_period * (pipeline_depth-1);
assert m2.valid = '1';
assert m2.write_reg_enable = '1';
assert m2.write_reg_nr = "10001";
assert m2.write_reg_data = x"0000000001111000";
assert m2.write_cr_enable = '1';
assert m2.write_cr_data = x"40000000";

-- test mulld
mulld_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
-- test mulld
mulld_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);

behave_rt := ppc_mulld(ra, rb);
behave_rt := ppc_mulld(ra, rb);

m1.data1 <= '0' & ra;
m1.data2 <= '0' & rb;
m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;
m1.data1 <= '0' & ra;
m1.data2 <= '0' & rb;
m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;

wait for clk_period;
wait for clk_period;

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
wait for clk_period * (pipeline_depth-1);

assert m2.valid = '1';
assert m2.valid = '1';

assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;
assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulld expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;

-- test mulhdu
mulhdu_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
-- test mulhdu
mulhdu_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);

behave_rt := ppc_mulhdu(ra, rb);
behave_rt := ppc_mulhdu(ra, rb);

m1.data1 <= '0' & ra;
m1.data2 <= '0' & rb;
m1.valid <= '1';
m1.insn_type <= OP_MUL_H64;
m1.data1 <= '0' & ra;
m1.data2 <= '0' & rb;
m1.valid <= '1';
m1.insn_type <= OP_MUL_H64;

wait for clk_period;
wait for clk_period;

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
wait for clk_period * (pipeline_depth-1);

assert m2.valid = '1';
assert m2.valid = '1';

assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;
assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhdu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;

-- test mulhd
mulhd_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
-- test mulhd
mulhd_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);

behave_rt := ppc_mulhd(ra, rb);
behave_rt := ppc_mulhd(ra, rb);

m1.data1 <= ra(63) & ra;
m1.data2 <= rb(63) & rb;
m1.valid <= '1';
m1.insn_type <= OP_MUL_H64;
m1.data1 <= ra(63) & ra;
m1.data2 <= rb(63) & rb;
m1.valid <= '1';
m1.insn_type <= OP_MUL_H64;

wait for clk_period;
wait for clk_period;

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
wait for clk_period * (pipeline_depth-1);

assert m2.valid = '1';
assert m2.valid = '1';

assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;
assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhd expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;

-- test mullw
mullw_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
-- test mullw
mullw_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);

behave_rt := ppc_mullw(ra, rb);
behave_rt := ppc_mullw(ra, rb);

m1.data1 <= (others => ra(31));
m1.data1(31 downto 0) <= ra(31 downto 0);
m1.data2 <= (others => rb(31));
m1.data2(31 downto 0) <= rb(31 downto 0);
m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;
m1.data1 <= (others => ra(31));
m1.data1(31 downto 0) <= ra(31 downto 0);
m1.data2 <= (others => rb(31));
m1.data2(31 downto 0) <= rb(31 downto 0);
m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;

wait for clk_period;
wait for clk_period;

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
wait for clk_period * (pipeline_depth-1);

assert m2.valid = '1';
assert m2.valid = '1';

assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;
assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mullw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;

-- test mulhw
mulhw_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
-- test mulhw
mulhw_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);

behave_rt := ppc_mulhw(ra, rb);
behave_rt := ppc_mulhw(ra, rb);

m1.data1 <= (others => ra(31));
m1.data1(31 downto 0) <= ra(31 downto 0);
m1.data2 <= (others => rb(31));
m1.data2(31 downto 0) <= rb(31 downto 0);
m1.valid <= '1';
m1.insn_type <= OP_MUL_H32;
m1.data1 <= (others => ra(31));
m1.data1(31 downto 0) <= ra(31 downto 0);
m1.data2 <= (others => rb(31));
m1.data2(31 downto 0) <= rb(31 downto 0);
m1.valid <= '1';
m1.insn_type <= OP_MUL_H32;

wait for clk_period;
wait for clk_period;

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
wait for clk_period * (pipeline_depth-1);

assert m2.valid = '1';
assert m2.valid = '1';

assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;
assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhw expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;

-- test mulhwu
mulhwu_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);
-- test mulhwu
mulhwu_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
rb := pseudorand(rb'length);

behave_rt := ppc_mulhwu(ra, rb);
behave_rt := ppc_mulhwu(ra, rb);

m1.data1 <= (others => '0');
m1.data1(31 downto 0) <= ra(31 downto 0);
m1.data2 <= (others => '0');
m1.data2(31 downto 0) <= rb(31 downto 0);
m1.valid <= '1';
m1.insn_type <= OP_MUL_H32;
m1.data1 <= (others => '0');
m1.data1(31 downto 0) <= ra(31 downto 0);
m1.data2 <= (others => '0');
m1.data2(31 downto 0) <= rb(31 downto 0);
m1.valid <= '1';
m1.insn_type <= OP_MUL_H32;

wait for clk_period;
wait for clk_period;

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
wait for clk_period * (pipeline_depth-1);

assert m2.valid = '1';
assert m2.valid = '1';

assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhwu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;
assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulhwu expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;

-- test mulli
mulli_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
si := pseudorand(si'length);
-- test mulli
mulli_loop : for i in 0 to 1000 loop
ra := pseudorand(ra'length);
si := pseudorand(si'length);

behave_rt := ppc_mulli(ra, si);
behave_rt := ppc_mulli(ra, si);

m1.data1 <= ra(63) & ra;
m1.data2 <= (others => si(15));
m1.data2(15 downto 0) <= si;
m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;
m1.data1 <= ra(63) & ra;
m1.data2 <= (others => si(15));
m1.data2(15 downto 0) <= si;
m1.valid <= '1';
m1.insn_type <= OP_MUL_L64;

wait for clk_period;
wait for clk_period;

m1.valid <= '0';
m1.valid <= '0';

wait for clk_period * (pipeline_depth-1);
wait for clk_period * (pipeline_depth-1);

assert m2.valid = '1';
assert m2.valid = '1';

assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;
assert to_hstring(behave_rt) = to_hstring(m2.write_reg_data)
report "bad mulli expected " & to_hstring(behave_rt) & " got " & to_hstring(m2.write_reg_data);
end loop;

assert false report "end of test" severity failure;
wait;
end process;
assert false report "end of test" severity failure;
wait;
end process;
end behave;

@ -6,64 +6,64 @@ library work;
use work.common.all;

entity register_file is
port(
clk : in std_logic;
port(
clk : in std_logic;

d_in : in Decode2ToRegisterFileType;
d_out : out RegisterFileToDecode2Type;
d_in : in Decode2ToRegisterFileType;
d_out : out RegisterFileToDecode2Type;

w_in : in WritebackToRegisterFileType;
w_in : in WritebackToRegisterFileType;

-- debug
registers_out : out regfile
);
-- debug
registers_out : out regfile
);
end entity register_file;

architecture behaviour of register_file is
signal registers : regfile := (others => (others => '0'));
signal registers : regfile := (others => (others => '0'));
begin
-- synchronous writes
register_write_0: process(clk)
begin
if rising_edge(clk) then
if w_in.write_enable = '1' then
assert not(is_x(w_in.write_data)) and not(is_x(w_in.write_reg)) severity failure;
report "Writing GPR " & to_hstring(w_in.write_reg) & " " & to_hstring(w_in.write_data);
registers(to_integer(unsigned(w_in.write_reg))) <= w_in.write_data;
end if;
end if;
end process register_write_0;
-- synchronous writes
register_write_0: process(clk)
begin
if rising_edge(clk) then
if w_in.write_enable = '1' then
assert not(is_x(w_in.write_data)) and not(is_x(w_in.write_reg)) severity failure;
report "Writing GPR " & to_hstring(w_in.write_reg) & " " & to_hstring(w_in.write_data);
registers(to_integer(unsigned(w_in.write_reg))) <= w_in.write_data;
end if;
end if;
end process register_write_0;

-- asynchronous reads
register_read_0: process(all)
begin
if d_in.read1_enable = '1' then
report "Reading GPR " & to_hstring(d_in.read1_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read1_reg))));
end if;
if d_in.read2_enable = '1' then
report "Reading GPR " & to_hstring(d_in.read2_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read2_reg))));
end if;
if d_in.read3_enable = '1' then
report "Reading GPR " & to_hstring(d_in.read3_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read3_reg))));
end if;
d_out.read1_data <= registers(to_integer(unsigned(d_in.read1_reg)));
d_out.read2_data <= registers(to_integer(unsigned(d_in.read2_reg)));
d_out.read3_data <= registers(to_integer(unsigned(d_in.read3_reg)));
-- asynchronous reads
register_read_0: process(all)
begin
if d_in.read1_enable = '1' then
report "Reading GPR " & to_hstring(d_in.read1_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read1_reg))));
end if;
if d_in.read2_enable = '1' then
report "Reading GPR " & to_hstring(d_in.read2_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read2_reg))));
end if;
if d_in.read3_enable = '1' then
report "Reading GPR " & to_hstring(d_in.read3_reg) & " " & to_hstring(registers(to_integer(unsigned(d_in.read3_reg))));
end if;
d_out.read1_data <= registers(to_integer(unsigned(d_in.read1_reg)));
d_out.read2_data <= registers(to_integer(unsigned(d_in.read2_reg)));
d_out.read3_data <= registers(to_integer(unsigned(d_in.read3_reg)));

-- Forward any written data
if w_in.write_enable = '1' then
if d_in.read1_reg = w_in.write_reg then
d_out.read1_data <= w_in.write_data;
end if;
if d_in.read2_reg = w_in.write_reg then
d_out.read2_data <= w_in.write_data;
end if;
if d_in.read3_reg = w_in.write_reg then
d_out.read3_data <= w_in.write_data;
end if;
end if;
end process register_read_0;
-- Forward any written data
if w_in.write_enable = '1' then
if d_in.read1_reg = w_in.write_reg then
d_out.read1_data <= w_in.write_data;
end if;
if d_in.read2_reg = w_in.write_reg then
d_out.read2_data <= w_in.write_data;
end if;
if d_in.read3_reg = w_in.write_reg then
d_out.read3_data <= w_in.write_data;
end if;
end if;
end process register_read_0;

-- debug
registers_out <= registers;
-- debug
registers_out <= registers;
end architecture behaviour;

@ -2,29 +2,29 @@ library ieee;
use ieee.std_logic_1164.all;

package sim_console is
procedure sim_console_read (val: out std_ulogic_vector(63 downto 0));
attribute foreign of sim_console_read : procedure is "VHPIDIRECT sim_console_read";
procedure sim_console_read (val: out std_ulogic_vector(63 downto 0));
attribute foreign of sim_console_read : procedure is "VHPIDIRECT sim_console_read";

procedure sim_console_poll (val: out std_ulogic_vector(63 downto 0));
attribute foreign of sim_console_poll : procedure is "VHPIDIRECT sim_console_poll";
procedure sim_console_poll (val: out std_ulogic_vector(63 downto 0));
attribute foreign of sim_console_poll : procedure is "VHPIDIRECT sim_console_poll";

procedure sim_console_write (val: std_ulogic_vector(63 downto 0));
attribute foreign of sim_console_write : procedure is "VHPIDIRECT sim_console_write";
procedure sim_console_write (val: std_ulogic_vector(63 downto 0));
attribute foreign of sim_console_write : procedure is "VHPIDIRECT sim_console_write";
end sim_console;

package body sim_console is
procedure sim_console_read (val: out std_ulogic_vector(63 downto 0)) is
begin
assert false report "VHPI" severity failure;
end sim_console_read;
procedure sim_console_read (val: out std_ulogic_vector(63 downto 0)) is
begin
assert false report "VHPI" severity failure;
end sim_console_read;

procedure sim_console_poll (val: out std_ulogic_vector(63 downto 0)) is
begin
assert false report "VHPI" severity failure;
end sim_console_poll;
procedure sim_console_poll (val: out std_ulogic_vector(63 downto 0)) is
begin
assert false report "VHPI" severity failure;
end sim_console_poll;

procedure sim_console_write (val: std_ulogic_vector(63 downto 0)) is
begin
assert false report "VHPI" severity failure;
end sim_console_write;
procedure sim_console_write (val: std_ulogic_vector(63 downto 0)) is
begin
assert false report "VHPI" severity failure;
end sim_console_write;
end sim_console;

@ -8,70 +8,70 @@ use work.wishbone_types.all;
use work.simple_ram_behavioural_helpers.all;

entity mw_soc_memory is
generic (
RAM_INIT_FILE : string;
MEMORY_SIZE : integer
);
generic (
RAM_INIT_FILE : string;
MEMORY_SIZE : integer
);

port (
clk : in std_ulogic;
rst : in std_ulogic;
port (
clk : in std_ulogic;
rst : in std_ulogic;

wishbone_in : in wishbone_master_out;
wishbone_out : out wishbone_slave_out
);
wishbone_in : in wishbone_master_out;
wishbone_out : out wishbone_slave_out
);
end mw_soc_memory;

architecture behave of mw_soc_memory is
type wishbone_state_t is (IDLE, ACK);
type wishbone_state_t is (IDLE, ACK);

signal state : wishbone_state_t := IDLE;
signal ret_ack : std_ulogic := '0';
signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, size => MEMORY_SIZE);
signal reload : integer := 0;
signal state : wishbone_state_t := IDLE;
signal ret_ack : std_ulogic := '0';
signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, size => MEMORY_SIZE);
signal reload : integer := 0;
begin
wishbone_process: process(clk)
variable ret_dat: std_ulogic_vector(63 downto 0) := (others => '0');
begin
wishbone_out.ack <= ret_ack and wishbone_in.cyc and wishbone_in.stb;
wishbone_out.dat <= ret_dat;
wishbone_process: process(clk)
variable ret_dat: std_ulogic_vector(63 downto 0) := (others => '0');
begin
wishbone_out.ack <= ret_ack and wishbone_in.cyc and wishbone_in.stb;
wishbone_out.dat <= ret_dat;

if rising_edge(clk) then
if rst = '1' then
state <= IDLE;
ret_ack <= '0';
else
ret_dat := x"FFFFFFFFFFFFFFFF";
if rising_edge(clk) then
if rst = '1' then
state <= IDLE;
ret_ack <= '0';
else
ret_dat := x"FFFFFFFFFFFFFFFF";

-- Active
if wishbone_in.cyc = '1' then
case state is
when IDLE =>
if wishbone_in.stb = '1' then
-- write
if wishbone_in.we = '1' then
assert not(is_x(wishbone_in.dat)) and not(is_x(wishbone_in.adr)) severity failure;
report "RAM writing " & to_hstring(wishbone_in.dat) & " to " & to_hstring(wishbone_in.adr);
behavioural_write(wishbone_in.dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier);
reload <= reload + 1;
ret_ack <= '1';
state <= ACK;
else
behavioural_read(ret_dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier, reload);
report "RAM reading from " & to_hstring(wishbone_in.adr) & " returns " & to_hstring(ret_dat);
ret_ack <= '1';
state <= ACK;
end if;
end if;
when ACK =>
ret_ack <= '0';
state <= IDLE;
end case;
else
ret_ack <= '0';
state <= IDLE;
end if;
end if;
end if;
end process;
-- Active
if wishbone_in.cyc = '1' then
case state is
when IDLE =>
if wishbone_in.stb = '1' then
-- write
if wishbone_in.we = '1' then
assert not(is_x(wishbone_in.dat)) and not(is_x(wishbone_in.adr)) severity failure;
report "RAM writing " & to_hstring(wishbone_in.dat) & " to " & to_hstring(wishbone_in.adr);
behavioural_write(wishbone_in.dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier);
reload <= reload + 1;
ret_ack <= '1';
state <= ACK;
else
behavioural_read(ret_dat, wishbone_in.adr, to_integer(unsigned(wishbone_in.sel)), identifier, reload);
report "RAM reading from " & to_hstring(wishbone_in.adr) & " returns " & to_hstring(ret_dat);
ret_ack <= '1';
state <= ACK;
end if;
end if;
when ACK =>
ret_ack <= '0';
state <= IDLE;
end case;
else
ret_ack <= '0';
state <= IDLE;
end if;
end if;
end if;
end process;
end behave;

@ -2,29 +2,29 @@ library ieee;
use ieee.std_logic_1164.all;

package simple_ram_behavioural_helpers is
function behavioural_initialize (filename: String; size: integer) return integer;
attribute foreign of behavioural_initialize : function is "VHPIDIRECT behavioural_initialize";
function behavioural_initialize (filename: String; size: integer) return integer;
attribute foreign of behavioural_initialize : function is "VHPIDIRECT behavioural_initialize";

procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer);
attribute foreign of behavioural_read : procedure is "VHPIDIRECT behavioural_read";
procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer);
attribute foreign of behavioural_read : procedure is "VHPIDIRECT behavioural_read";

procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer);
attribute foreign of behavioural_write : procedure is "VHPIDIRECT behavioural_write";
procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer);
attribute foreign of behavioural_write : procedure is "VHPIDIRECT behavioural_write";
end simple_ram_behavioural_helpers;

package body simple_ram_behavioural_helpers is
function behavioural_initialize (filename: String; size: integer) return integer is
begin
assert false report "VHPI" severity failure;
end behavioural_initialize;
function behavioural_initialize (filename: String; size: integer) return integer is
begin
assert false report "VHPI" severity failure;
end behavioural_initialize;

procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer) is
begin
assert false report "VHPI" severity failure;
end behavioural_read;
procedure behavioural_read (val: out std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer; reload: integer) is
begin
assert false report "VHPI" severity failure;
end behavioural_read;

procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer) is
begin
assert false report "VHPI" severity failure;
end behavioural_write;
procedure behavioural_write (val: std_ulogic_vector(63 downto 0); addr: std_ulogic_vector(63 downto 0); length: integer; identifier: integer) is
begin
assert false report "VHPI" severity failure;
end behavioural_write;
end simple_ram_behavioural_helpers;

@ -9,225 +9,233 @@ entity simple_ram_behavioural_tb is
end simple_ram_behavioural_tb;

architecture behave of simple_ram_behavioural_tb is
signal clk : std_ulogic;
signal rst : std_ulogic := '1';
signal clk : std_ulogic;
signal rst : std_ulogic := '1';

constant clk_period : time := 10 ns;
constant clk_period : time := 10 ns;

signal w_in : wishbone_slave_out;
signal w_out : wishbone_master_out;
signal w_in : wishbone_slave_out;
signal w_out : wishbone_master_out;
begin
simple_ram_0: entity work.mw_soc_memory
generic map ( RAM_INIT_FILE => "simple_ram_behavioural_tb.bin", MEMORY_SIZE => 16 )
port map (clk => clk, rst => rst, wishbone_out => w_in, wishbone_in => w_out);

clock: process
begin
clk <= '1';
wait for clk_period / 2;
clk <= '0';
wait for clk_period / 2;
end process clock;

stim: process
begin
w_out.adr <= (others => '0');
w_out.dat <= (others => '0');
w_out.cyc <= '0';
w_out.stb <= '0';
w_out.sel <= (others => '0');
w_out.we <= '0';

wait for clk_period;
rst <= '0';

wait for clk_period;

w_out.cyc <= '1';

-- test various read lengths and alignments
w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"00" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"01" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"07" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000011";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(15 downto 0) = x"0100" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000011";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(15 downto 0) = x"0201" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000011";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(15 downto 0) = x"0807" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00001111";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(31 downto 0) = x"03020100" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00001111";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(31 downto 0) = x"04030201" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00001111";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(31 downto 0) = x"0A090807" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(63 downto 0) = x"0706050403020100" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(63 downto 0) = x"0807060504030201" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(63 downto 0) = x"0E0D0C0B0A090807" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

-- test various write lengths and alignments
w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000000";
w_out.we <= '1';
w_out.dat(7 downto 0) <= x"0F";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000000";
w_out.we <= '0';
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"0F" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000007";
w_out.we <= '1';
w_out.dat <= x"BADC0FFEBADC0FFE";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000007";
w_out.we <= '0';
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat = x"BADC0FFEBADC0FFE" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

assert false report "end of test" severity failure;
wait;
end process;
simple_ram_0: entity work.mw_soc_memory
generic map (
RAM_INIT_FILE => "simple_ram_behavioural_tb.bin",
MEMORY_SIZE => 16
)
port map (
clk => clk,
rst => rst,
wishbone_out => w_in,
wishbone_in => w_out
);

clock: process
begin
clk <= '1';
wait for clk_period / 2;
clk <= '0';
wait for clk_period / 2;
end process clock;

stim: process
begin
w_out.adr <= (others => '0');
w_out.dat <= (others => '0');
w_out.cyc <= '0';
w_out.stb <= '0';
w_out.sel <= (others => '0');
w_out.we <= '0';

wait for clk_period;
rst <= '0';

wait for clk_period;

w_out.cyc <= '1';

-- test various read lengths and alignments
w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"00" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"01" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"07" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000011";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(15 downto 0) = x"0100" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000011";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(15 downto 0) = x"0201" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000011";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(15 downto 0) = x"0807" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00001111";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(31 downto 0) = x"03020100" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00001111";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(31 downto 0) = x"04030201" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00001111";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(31 downto 0) = x"0A090807" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000000";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(63 downto 0) = x"0706050403020100" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000001";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(63 downto 0) = x"0807060504030201" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000007";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(63 downto 0) = x"0E0D0C0B0A090807" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

-- test various write lengths and alignments
w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000000";
w_out.we <= '1';
w_out.dat(7 downto 0) <= x"0F";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "00000001";
w_out.adr <= x"0000000000000000";
w_out.we <= '0';
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat(7 downto 0) = x"0F" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000007";
w_out.we <= '1';
w_out.dat <= x"BADC0FFEBADC0FFE";
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

w_out.stb <= '1';
w_out.sel <= "11111111";
w_out.adr <= x"0000000000000007";
w_out.we <= '0';
assert w_in.ack = '0';
wait for clk_period;
assert w_in.ack = '1';
assert w_in.dat = x"BADC0FFEBADC0FFE" report to_hstring(w_in.dat);
w_out.stb <= '0';
wait for clk_period;
assert w_in.ack = '0';

assert false report "end of test" severity failure;
wait;
end process;
end behave;

@ -5,53 +5,53 @@ library work;
use work.wishbone_types.all;

entity wishbone_arbiter is
port (
clk : in std_ulogic;
rst : in std_ulogic;
port (
clk : in std_ulogic;
rst : in std_ulogic;

wb1_in : in wishbone_master_out;
wb1_out : out wishbone_slave_out;
wb1_in : in wishbone_master_out;
wb1_out : out wishbone_slave_out;

wb2_in : in wishbone_master_out;
wb2_out : out wishbone_slave_out;
wb2_in : in wishbone_master_out;
wb2_out : out wishbone_slave_out;

wb_out : out wishbone_master_out;
wb_in : in wishbone_slave_out
);
wb_out : out wishbone_master_out;
wb_in : in wishbone_slave_out
);
end wishbone_arbiter;

architecture behave of wishbone_arbiter is
type wishbone_arbiter_state_t is (IDLE, WB1_BUSY, WB2_BUSY);
signal state : wishbone_arbiter_state_t := IDLE;
type wishbone_arbiter_state_t is (IDLE, WB1_BUSY, WB2_BUSY);
signal state : wishbone_arbiter_state_t := IDLE;
begin
wb1_out <= wb_in when state = WB1_BUSY else wishbone_slave_out_init;
wb2_out <= wb_in when state = WB2_BUSY else wishbone_slave_out_init;

wb_out <= wb1_in when state = WB1_BUSY else wb2_in when state = WB2_BUSY else wishbone_master_out_init;

wishbone_arbiter_process: process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
state <= IDLE;
else
case state is
when IDLE =>
if wb1_in.cyc = '1' then
state <= WB1_BUSY;
elsif wb2_in.cyc = '1' then
state <= WB2_BUSY;
end if;
when WB1_BUSY =>
if wb1_in.cyc = '0' then
state <= IDLE;
end if;
when WB2_BUSY =>
if wb2_in.cyc = '0' then
state <= IDLE;
end if;
end case;
end if;
end if;
end process;
wb1_out <= wb_in when state = WB1_BUSY else wishbone_slave_out_init;
wb2_out <= wb_in when state = WB2_BUSY else wishbone_slave_out_init;

wb_out <= wb1_in when state = WB1_BUSY else wb2_in when state = WB2_BUSY else wishbone_master_out_init;

wishbone_arbiter_process: process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
state <= IDLE;
else
case state is
when IDLE =>
if wb1_in.cyc = '1' then
state <= WB1_BUSY;
elsif wb2_in.cyc = '1' then
state <= WB2_BUSY;
end if;
when WB1_BUSY =>
if wb1_in.cyc = '0' then
state <= IDLE;
end if;
when WB2_BUSY =>
if wb2_in.cyc = '0' then
state <= IDLE;
end if;
end case;
end if;
end if;
end process;
end behave;

@ -2,26 +2,26 @@ library ieee;
use ieee.std_logic_1164.all;

package wishbone_types is
constant wishbone_addr_bits : integer := 64;
constant wishbone_data_bits : integer := 64;
constant wishbone_addr_bits : integer := 64;
constant wishbone_data_bits : integer := 64;

subtype wishbone_addr_type is std_ulogic_vector(wishbone_addr_bits-1 downto 0);
subtype wishbone_data_type is std_ulogic_vector(wishbone_data_bits-1 downto 0);
subtype wishbone_addr_type is std_ulogic_vector(wishbone_addr_bits-1 downto 0);
subtype wishbone_data_type is std_ulogic_vector(wishbone_data_bits-1 downto 0);

type wishbone_master_out is record
adr : wishbone_addr_type;
dat : wishbone_data_type;
cyc : std_ulogic;
stb : std_ulogic;
sel : std_ulogic_vector(7 downto 0);
we : std_ulogic;
end record;
constant wishbone_master_out_init : wishbone_master_out := (cyc => '0', stb => '0', we => '0', others => (others => '0'));
type wishbone_master_out is record
adr : wishbone_addr_type;
dat : wishbone_data_type;
cyc : std_ulogic;
stb : std_ulogic;
sel : std_ulogic_vector(7 downto 0);
we : std_ulogic;
end record;
constant wishbone_master_out_init : wishbone_master_out := (cyc => '0', stb => '0', we => '0', others => (others => '0'));

type wishbone_slave_out is record
dat : wishbone_data_type;
ack : std_ulogic;
end record;
constant wishbone_slave_out_init : wishbone_slave_out := (ack => '0', others => (others => '0'));
type wishbone_slave_out is record
dat : wishbone_data_type;
ack : std_ulogic;
end record;
constant wishbone_slave_out_init : wishbone_slave_out := (ack => '0', others => (others => '0'));

end package wishbone_types;

Loading…
Cancel
Save