cpu: wait when mem_busy is high
This commit is contained in:
parent
634596fd0f
commit
1e6dc25c88
27
cpu/cpu.vhdl
27
cpu/cpu.vhdl
@ -14,7 +14,8 @@ entity cpu is
|
||||
mem_out: out std_logic_vector(15 downto 0);
|
||||
mem_addr: out std_logic_vector(15 downto 0);
|
||||
mem_write: out std_logic;
|
||||
mem_read: out std_logic
|
||||
mem_read: out std_logic;
|
||||
mem_busy: in std_logic
|
||||
);
|
||||
end entity cpu;
|
||||
|
||||
@ -48,18 +49,20 @@ architecture behavior of cpu is
|
||||
|
||||
signal load_reg_next, load_reg: std_logic_vector(15 downto 0);
|
||||
signal load_addr_next, load_addr: std_logic_vector(15 downto 0);
|
||||
signal hold_inst_next, hold_inst: std_logic_vector(15 downto 0);
|
||||
|
||||
type regbank is array(0 to 15) of std_logic_vector(15 downto 0);
|
||||
signal reg_d: regbank;
|
||||
signal reg_q: regbank;
|
||||
|
||||
type cpu_state_t is (RUN, LOAD, BRANCH);
|
||||
type cpu_state_t is (RUN, LOAD, BRANCH, WAIT_MEM);
|
||||
signal cpu_state, cpu_state_next: cpu_state_t;
|
||||
begin
|
||||
cpu_alu: alu port map(a => alu_a, b => alu_b, sel => alu_sel, flag => alu_flag, q => alu_q);
|
||||
|
||||
load_reg_r: reg port map(clk => clk, rst => rst, d => load_reg_next, q => load_reg);
|
||||
load_addr_r: reg port map(clk => clk, rst => rst, d => load_addr_next, q => load_addr);
|
||||
hold_inst_r: reg port map(clk => clk, rst => rst, d => hold_inst_next, q => hold_inst);
|
||||
|
||||
allregs:
|
||||
for i in 0 to 15 generate
|
||||
@ -77,7 +80,7 @@ begin
|
||||
|
||||
code_addr <= reg_q(14);
|
||||
|
||||
process(code_data, reg_q, mem_in, alu_q, alu_flag, cpu_state, load_addr, load_reg) is
|
||||
process(code_data, reg_q, mem_in, mem_busy, alu_q, alu_flag, cpu_state, load_addr, load_reg) is
|
||||
variable inst: std_logic_vector(15 downto 0);
|
||||
variable regn_0: natural;
|
||||
variable regn_1: natural;
|
||||
@ -103,6 +106,7 @@ begin
|
||||
|
||||
load_reg_next <= load_reg;
|
||||
load_addr_next <= load_addr;
|
||||
hold_inst_next <= hold_inst;
|
||||
|
||||
case cpu_state is
|
||||
when RUN =>
|
||||
@ -122,6 +126,10 @@ begin
|
||||
when BRANCH =>
|
||||
inst := x"0000"; -- NOP
|
||||
reg_d(14) <= std_logic_vector(unsigned(reg_q(14)) + 2);
|
||||
when WAIT_MEM =>
|
||||
cpu_state_next <= RUN;
|
||||
inst := hold_inst;
|
||||
reg_d(14) <= std_logic_vector(unsigned(reg_q(14)) + 2);
|
||||
end case;
|
||||
|
||||
regn_0 := to_integer(unsigned(inst(11 downto 8)));
|
||||
@ -131,6 +139,11 @@ begin
|
||||
case inst(15 downto 12) is
|
||||
when "0000" => -- NOP
|
||||
when "0001" => -- LOAD rn, [rm, imm] (imm is signed 4 bits)
|
||||
if mem_busy = '1' then
|
||||
reg_d(14) <= reg_q(14); -- halt the prefetcher
|
||||
hold_inst_next <= inst;
|
||||
cpu_state_next <= WAIT_MEM;
|
||||
else
|
||||
mem_read <= '1';
|
||||
cpu_state_next <= LOAD;
|
||||
reg_d(14) <= reg_q(14); -- halt the prefetcher
|
||||
@ -138,10 +151,18 @@ begin
|
||||
load_addr_next <= std_logic_vector(signed(reg_q(regn_1)) + signed(inst(3 downto 0) & '0'));
|
||||
mem_addr <= std_logic_vector(signed(reg_q(regn_1)) + signed(inst(3 downto 0) & '0'));
|
||||
load_reg_next(3 downto 0) <= inst(11 downto 8);
|
||||
end if;
|
||||
|
||||
when "0010" => -- STORE rn, [rm, imm]
|
||||
if mem_busy = '1' then
|
||||
reg_d(14) <= reg_q(14); -- halt the prefetcher
|
||||
hold_inst_next <= inst;
|
||||
cpu_state_next <= WAIT_MEM;
|
||||
else
|
||||
mem_write <= '1';
|
||||
mem_addr <= std_logic_vector(signed(reg_q(regn_1)) + signed(inst(3 downto 0) & '0'));
|
||||
mem_out <= reg_q(regn_0);
|
||||
end if;
|
||||
|
||||
--- ALU stuff
|
||||
when "0011" => do_alu := '1'; -- ADD rd, rn, rm (rd := rn + rm)
|
||||
|
@ -19,7 +19,8 @@ architecture rtl of cpu_test is
|
||||
mem_out: out std_logic_vector(15 downto 0);
|
||||
mem_addr: out std_logic_vector(15 downto 0);
|
||||
mem_write: out std_logic;
|
||||
mem_read: out std_logic
|
||||
mem_read: out std_logic;
|
||||
mem_busy: in std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
@ -40,14 +41,14 @@ architecture rtl of cpu_test is
|
||||
);
|
||||
|
||||
signal finished, clk, rst: std_logic := '0';
|
||||
signal mem_write, mem_read: std_logic;
|
||||
signal mem_write, mem_read, mem_busy: std_logic;
|
||||
signal rom_data, rom_addr, mem_in, mem_out, mem_addr: std_logic_vector(15 downto 0);
|
||||
|
||||
begin
|
||||
dut: cpu port map(clk => clk, rst => rst,
|
||||
code_data => rom_data, code_addr => rom_addr,
|
||||
mem_in => mem_in, mem_out => mem_out, mem_addr => mem_addr,
|
||||
mem_write => mem_write, mem_read => mem_read);
|
||||
mem_write => mem_write, mem_read => mem_read, mem_busy => mem_busy);
|
||||
|
||||
-- clock
|
||||
process
|
||||
@ -97,6 +98,14 @@ begin
|
||||
assert(mem_addr=x"0025") report "Fail set mem_addr to 0x25" severity error;
|
||||
assert(mem_out=x"002a") report "Fail set mem_out to 42" severity error;
|
||||
|
||||
mem_busy <= '1';
|
||||
|
||||
wait for 10 ns;
|
||||
assert(rom_addr=x"0008") report "Fail hold PC @08" severity error;
|
||||
assert(mem_read='0') report "Fail to wait until mem_busy is low" severity error;
|
||||
|
||||
mem_busy <= '0';
|
||||
|
||||
wait for 10 ns;
|
||||
assert(rom_addr=x"000a") report "Fail PC @08" severity error;
|
||||
assert(mem_write='0') report "Fail set mem_write to 0" severity error;
|
||||
|
Loading…
Reference in New Issue
Block a user