mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-29 04:51:16 +00:00
Merge pull request #64 from antonblanchard/reformat-3
Reformat some more files
This commit is contained in:
82
cr_file.vhdl
82
cr_file.vhdl
@@ -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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
-- 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;
|
||||
-- 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_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;
|
||||
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;
|
||||
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;
|
||||
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 registers
|
||||
rin <= v;
|
||||
|
||||
-- Update outputs
|
||||
e_out <= r;
|
||||
end process;
|
||||
-- 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;
|
||||
|
||||
350
multiply_tb.vhdl
350
multiply_tb.vhdl
@@ -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);
|
||||
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;
|
||||
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';
|
||||
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;
|
||||
rst <= '0';
|
||||
|
||||
wait for clk_period;
|
||||
wait for clk_period;
|
||||
|
||||
w_out.cyc <= '1';
|
||||
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';
|
||||
-- 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"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 <= "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"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"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 <= "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"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"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 <= "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"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"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';
|
||||
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';
|
||||
-- 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 <= "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 <= '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';
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user