📄 mips.vhd
字号:
---------------------------------------------------------
-- mips.vhd
-- David_Harris@hmc.edu 9/9/03
-- Model of subset of MIPS processor described in Ch 1
---------------------------------------------------------
---------------------------------------------------------
-- Entity Declarations
---------------------------------------------------------
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_UNSIGNED.all;
entity top is -- top-level design for testing
generic(width: integer := 8; -- default 8-bit datapath
regbits: integer := 3); -- and 3 bit register addresses (8 regs)
end;
library IEEE; use IEEE.STD_LOGIC_1164.all; use STD.TEXTIO.all;
use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.STD_LOGIC_ARITH.all;
entity memory is -- external memory accessed by MIPS
generic(width: integer);
port(clk, memwrite: in STD_LOGIC;
adr, writedata: in STD_LOGIC_VECTOR(width-1 downto 0);
memdata: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mips is -- simplified MIPS processor
generic(width: integer := 8; -- default 8-bit datapath
regbits: integer := 3); -- and 3 bit register addresses (8 regs)
port(clk, reset: in STD_LOGIC;
memdata: in STD_LOGIC_VECTOR(width-1 downto 0);
memread, memwrite: out STD_LOGIC;
adr, writedata: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity controller is -- control FSM
port(clk, reset: in STD_LOGIC;
op: in STD_LOGIC_VECTOR(5 downto 0);
zero: in STD_LOGIC;
memread, memwrite, alusrca, memtoreg,
iord, pcen, regwrite, regdst: out STD_LOGIC;
pcsource, alusrcb, aluop: out STD_LOGIC_VECTOR(1 downto 0);
irwrite: out STD_LOGIC_VECTOR(3 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity alucontrol is -- ALU control decoder
port(aluop: in STD_LOGIC_VECTOR(1 downto 0);
funct: in STD_LOGIC_VECTOR(5 downto 0);
alucont: out STD_LOGIC_VECTOR(2 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all;
entity datapath is -- MIPS datapath
generic(width, regbits: integer);
port(clk, reset: in STD_LOGIC;
memdata: in STD_LOGIC_VECTOR(width-1 downto 0);
alusrca, memtoreg, iord, pcen,
regwrite, regdst: in STD_LOGIC;
pcsource, alusrcb: in STD_LOGIC_VECTOR(1 downto 0);
irwrite: in STD_LOGIC_VECTOR(3 downto 0);
alucont: in STD_LOGIC_VECTOR(2 downto 0);
zero: out STD_LOGIC;
instr: out STD_LOGIC_VECTOR(31 downto 0);
adr, writedata: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_LOGIC_UNSIGNED.all;
entity alu is -- Arithmetic/Logic unit with add/sub, AND, OR, set less than
generic(width: integer);
port(a, b: in STD_LOGIC_VECTOR(width-1 downto 0);
alucont: in STD_LOGIC_VECTOR(2 downto 0);
result: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all; use IEEE.STD_LOGIC_ARITH.all;
entity regfile is -- three-port register file of 2**regbits words x width bits
generic(width, regbits: integer);
port(clk: in STD_LOGIC;
write: in STD_LOGIC;
ra1, ra2, wa: in STD_LOGIC_VECTOR(regbits-1 downto 0);
wd: in STD_LOGIC_VECTOR(width-1 downto 0);
rd1, rd2: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity zerodetect is -- true if all input bits are zero
generic(width: integer);
port(a: in STD_LOGIC_VECTOR(width-1 downto 0);
y: out STD_LOGIC);
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity flop is -- flip-flop
generic(width: integer);
port(clk: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(width-1 downto 0);
q: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity flopen is -- flip-flop with enable
generic(width: integer);
port(clk, en: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(width-1 downto 0);
q: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_ARITH.all;
entity flopenr is -- flip-flop with enable and synchronous reset
generic(width: integer);
port(clk, reset, en: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(width-1 downto 0);
q: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mux2 is -- two-input multiplexer
generic(width: integer);
port(d0, d1: in STD_LOGIC_VECTOR(width-1 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mux4 is -- four-input multiplexer
generic(width: integer);
port(d0, d1, d2, d3: in STD_LOGIC_VECTOR(width-1 downto 0);
s: in STD_LOGIC_VECTOR(1 downto 0);
y: out STD_LOGIC_VECTOR(width-1 downto 0));
end;
---------------------------------------------------------
-- Architecture Definitions
---------------------------------------------------------
architecture test of top is
component mips generic(width: integer := 8; -- default 8-bit datapath
regbits: integer := 3); -- and 3 bit register addresses (8 regs)
port(clk, reset: in STD_LOGIC;
memdata: in STD_LOGIC_VECTOR(width-1 downto 0);
memread, memwrite: out STD_LOGIC;
adr, writedata: out STD_LOGIC_VECTOR(width-1 downto 0));
end component;
component memory generic(width: integer);
port(clk, memwrite: in STD_LOGIC;
adr, writedata: in STD_LOGIC_VECTOR(width-1 downto 0);
memdata: out STD_LOGIC_VECTOR(width-1 downto 0));
end component;
signal clk, reset, memread, memwrite: STD_LOGIC;
signal memdata, adr, writedata: STD_LOGIC_VECTOR(width-1 downto 0);
begin
-- mips being tested
dut: mips generic map(width, regbits)
port map(clk, reset, memdata, memread, memwrite, adr, writedata);
-- external memory for code and data
exmem: memory generic map(width)
port map(clk, memwrite, adr, writedata, memdata);
-- Generate clock with 10 ns period
process begin
clk <= '1';
wait for 5 ns;
clk <= '0';
wait for 5 ns;
end process;
-- Generate reset for first two clock cycles
process begin
reset <= '1';
wait for 22 ns;
reset <= '0';
wait;
end process;
-- check that 7 gets written to address 5 at end of program
process (clk) begin
if (clk'event and clk = '0' and memwrite = '1') then
if (conv_integer(adr) = 5 and conv_integer(writedata) = 7) then
report "Simulation completed successfully";
else report "Simulation failed.";
end if;
end if;
end process;
end;
architecture behave of memory is
begin
process is
file mem_file: text open read_mode is "memfile.dat";
variable L: line;
variable ch: character;
variable index, result: integer;
type ramtype is array (511 downto 0) of STD_LOGIC_VECTOR(7 downto 0);
variable mem: ramtype;
begin
-- initialize memory from file
for i in 0 to 511 loop -- set all contents low
mem(conv_integer(i)) := "00000000";
end loop;
index := 0;
while not endfile(mem_file) loop
readline(mem_file, L);
for j in 0 to 3 loop
result := 0;
for i in 1 to 2 loop
read(L, ch);
if '0' <= ch and ch <= '9' then
result := result*16 + character'pos(ch)-character'pos('0');
elsif 'a' <= ch and ch <= 'f' then
result := result*16 + character'pos(ch)-character'pos('a')+10;
else report "Format error on line " & integer'image(index)
severity error;
end if;
end loop;
mem(index*4+j) := conv_std_logic_vector(result, width);
end loop;
index := index + 1;
end loop;
-- read or write memory
loop
if clk'event and clk = '1' then
if (memwrite = '1') then mem(conv_integer(adr)) := writedata;
end if;
end if;
memdata <= mem(conv_integer(adr));
wait on clk, adr;
end loop;
end process;
end;
architecture struct of mips is
component controller
port(clk, reset: in STD_LOGIC;
op: in STD_LOGIC_VECTOR(5 downto 0);
zero: in STD_LOGIC;
memread, memwrite, alusrca, memtoreg,
iord, pcen, regwrite, regdst: out STD_LOGIC;
pcsource, alusrcb, aluop: out STD_LOGIC_VECTOR(1 downto 0);
irwrite: out STD_LOGIC_VECTOR(3 downto 0));
end component;
component alucontrol
port(aluop: in STD_LOGIC_VECTOR(1 downto 0);
funct: in STD_LOGIC_VECTOR(5 downto 0);
alucont: out STD_LOGIC_VECTOR(2 downto 0));
end component;
component datapath generic(width, regbits: integer);
port(clk, reset: in STD_LOGIC;
memdata: in STD_LOGIC_VECTOR(width-1 downto 0);
alusrca, memtoreg, iord, pcen,
regwrite, regdst: in STD_LOGIC;
pcsource, alusrcb: in STD_LOGIC_VECTOR(1 downto 0);
irwrite: in STD_LOGIC_VECTOR(3 downto 0);
alucont: in STD_LOGIC_VECTOR(2 downto 0);
zero: out STD_LOGIC;
instr: out STD_LOGIC_VECTOR(31 downto 0);
adr, writedata: out STD_LOGIC_VECTOR(width-1 downto 0));
end component;
signal instr: STD_LOGIC_VECTOR(31 downto 0);
signal zero, alusrca, memtoreg, iord, pcen, regwrite, regdst: STD_LOGIC;
signal aluop, pcsource, alusrcb: STD_LOGIC_VECTOR(1 downto 0);
signal irwrite: STD_LOGIC_VECTOR(3 downto 0);
signal alucont: STD_LOGIC_VECTOR(2 downto 0);
begin
cont: controller port map(clk, reset, instr(31 downto 26), zero,
memread, memwrite, alusrca, memtoreg,
iord, pcen, regwrite, regdst,
pcsource, alusrcb, aluop, irwrite);
ac: alucontrol port map(aluop, instr(5 downto 0), alucont);
dp: datapath generic map(width, regbits)
port map(clk, reset, memdata, alusrca, memtoreg,
iord, pcen, regwrite, regdst,
pcsource, alusrcb, irwrite,
alucont, zero, instr, adr, writedata);
end;
architecture behave of controller is
type statetype is (FETCH1, FETCH2, FETCH3, FETCH4, DECODE, MEMADR,
LBRD, LBWR, SBWR, RTYPEEX, RTYPEWR, BEQEX, JEX);
constant LB: STD_LOGIC_VECTOR(5 downto 0) := "100000";
constant SB: STD_LOGIC_VECTOR(5 downto 0) := "101000";
constant RTYPE: STD_LOGIC_VECTOR(5 downto 0) := "000000";
constant BEQ: STD_LOGIC_VECTOR(5 downto 0) := "000100";
constant J: STD_LOGIC_VECTOR(5 downto 0) := "000010";
signal state, nextstate: statetype;
signal pcwrite, pcwritecond: STD_LOGIC;
begin
process (clk) begin -- state register
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -