Initial commit
This commit is contained in:
57
first/adder.vhdl
Normal file
57
first/adder.vhdl
Normal file
@@ -0,0 +1,57 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
entity adder is
|
||||
port(
|
||||
a : in std_logic;
|
||||
b : in std_logic;
|
||||
c_in : in std_logic;
|
||||
|
||||
q : out std_logic;
|
||||
c_out : out std_logic
|
||||
);
|
||||
end entity adder;
|
||||
|
||||
architecture behavior of adder is
|
||||
|
||||
begin
|
||||
|
||||
q <= (a xor b) xor c_in;
|
||||
c_out <= (a and b) or (a and c_in) or (b and c_in);
|
||||
|
||||
end architecture behavior;
|
||||
|
||||
---
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
entity vect_adder is
|
||||
generic(SIZE: natural := 16);
|
||||
port(
|
||||
a : in std_logic_vector(SIZE-1 downto 0);
|
||||
b : in std_logic_vector(SIZE-1 downto 0);
|
||||
c_in : in std_logic;
|
||||
|
||||
q : out std_logic_vector(SIZE-1 downto 0);
|
||||
c_out : out std_logic
|
||||
);
|
||||
end entity vect_adder;
|
||||
|
||||
architecture behavior of vect_adder is
|
||||
|
||||
component adder port(a, b, c_in: in std_logic; q, c_out: out std_logic);
|
||||
end component;
|
||||
|
||||
signal carry: std_logic_vector(SIZE downto 0);
|
||||
|
||||
begin
|
||||
|
||||
adders:
|
||||
for i in 0 to SIZE-1 generate
|
||||
addx: adder port map(a(i), b(i), carry(i), q(i), carry(i + 1));
|
||||
end generate adders;
|
||||
|
||||
carry(0) <= c_in;
|
||||
c_out <= carry(SIZE);
|
||||
|
||||
end architecture behavior;
|
48
first/adder_test.vhdl
Normal file
48
first/adder_test.vhdl
Normal file
@@ -0,0 +1,48 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity vect_adder_test is
|
||||
end vect_adder_test;
|
||||
|
||||
architecture rtl of vect_adder_test is
|
||||
|
||||
component vect_adder is
|
||||
port(
|
||||
a, b : in std_logic_vector(15 downto 0);
|
||||
c_in : in std_logic;
|
||||
|
||||
q : out std_logic_vector(15 downto 0);
|
||||
c_out : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal a, b, q: std_logic_vector(15 downto 0);
|
||||
signal c_in, c_out: std_logic;
|
||||
|
||||
begin
|
||||
dut: vect_adder port map(a, b, c_in, q, c_out);
|
||||
|
||||
process
|
||||
begin
|
||||
|
||||
a <= "0000000000000001";
|
||||
b <= "0000000000000001";
|
||||
c_in <= '0';
|
||||
|
||||
wait for 1 ns;
|
||||
assert(q="0000000000000010") report "Fail 1+1" severity error;
|
||||
assert(c_out='0') report "Fail carry 1+1" severity error;
|
||||
|
||||
a <= "1111111111111111";
|
||||
b <= "0000000000000001";
|
||||
c_in <= '0';
|
||||
|
||||
wait for 1 ns;
|
||||
assert(q="0000000000000000") report "Fail 0xffff + 1" severity error;
|
||||
assert(c_out='1') report "Fail carry 0xffff + 1" severity error;
|
||||
-- end
|
||||
assert false report "Test done." severity note;
|
||||
wait;
|
||||
end process;
|
||||
end rtl;
|
70
first/alu.vhdl
Normal file
70
first/alu.vhdl
Normal file
@@ -0,0 +1,70 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity alu is
|
||||
port(
|
||||
a: in std_logic_vector(15 downto 0);
|
||||
b: in std_logic_vector(15 downto 0);
|
||||
sel: in std_logic_vector(3 downto 0);
|
||||
|
||||
flag: out std_logic;
|
||||
q: out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end alu;
|
||||
|
||||
architecture behavior of alu is
|
||||
begin
|
||||
|
||||
process(a, b, sel) is
|
||||
variable tmp: std_logic_vector(31 downto 0);
|
||||
variable idx: natural;
|
||||
begin
|
||||
|
||||
q <= x"0000";
|
||||
flag <= '0';
|
||||
tmp := x"00000000";
|
||||
idx := 0;
|
||||
|
||||
case sel is
|
||||
when "0011" => -- q = a + b, flag is carry
|
||||
tmp(16 downto 0) := std_logic_vector(unsigned('0' & a) + unsigned(b));
|
||||
q <= tmp(15 downto 0);
|
||||
flag <= tmp(16);
|
||||
when "0100" => -- q = a - b, flag if a < b
|
||||
tmp(16 downto 0) := std_logic_vector(unsigned('1' & a) - unsigned(b));
|
||||
q <= tmp(15 downto 0);
|
||||
flag <= not tmp(16);
|
||||
when "0101" => q <= a or b;
|
||||
when "0110" => q <= a and b;
|
||||
when "0111" => q <= not a;
|
||||
when "1000" => q <= a xor b;
|
||||
when "1001" => -- left shift by 1
|
||||
q <= a(14 downto 0) & '0';
|
||||
flag <= a(15);
|
||||
when "1010" => -- right shift by b(3 downto 0)
|
||||
idx := to_integer(unsigned(b(3 downto 0)));
|
||||
tmp(15 - idx downto 0) := a(15 downto idx);
|
||||
q <= tmp(15 downto 0);
|
||||
flag <= a(0);
|
||||
when "1011" => -- q = a * b
|
||||
--tmp := std_logic_vector(unsigned(a) * unsigned(b));
|
||||
q <= tmp(15 downto 0);
|
||||
when "1100" => -- flag if a = b
|
||||
if (a = b) then
|
||||
flag <= '1';
|
||||
else
|
||||
flag <= '0';
|
||||
end if;
|
||||
|
||||
--- room for a few more things:
|
||||
-- - rotate
|
||||
-- - not / nand
|
||||
-- - gt...
|
||||
|
||||
when others =>
|
||||
-- do nothing
|
||||
end case;
|
||||
end process;
|
||||
|
||||
end behavior;
|
22
first/blinky.s
Normal file
22
first/blinky.s
Normal file
@@ -0,0 +1,22 @@
|
||||
begin:
|
||||
set r1, 128 // address of the LED
|
||||
set r2, 0
|
||||
set r3, 1
|
||||
set r4, 255 // outer counter limit
|
||||
|
||||
loop:
|
||||
store r2, [r1]
|
||||
add r2, r2, r3
|
||||
set r13, loop
|
||||
|
||||
delay:
|
||||
set r10, 0
|
||||
set r11, 0
|
||||
|
||||
delay_loop:
|
||||
add r10, r10, r3
|
||||
bneq delay_loop // flag will be 1 when it wraps
|
||||
add r11, r11, r3
|
||||
cmp r11, r4
|
||||
bneq delay_loop
|
||||
set pc, loop
|
142
first/boot_rom.vhdl
Normal file
142
first/boot_rom.vhdl
Normal file
@@ -0,0 +1,142 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity boot_rom is
|
||||
generic
|
||||
(
|
||||
addressWidth : in positive := 16;
|
||||
busWidth : in positive := 16
|
||||
);
|
||||
port
|
||||
(
|
||||
clk: in std_logic;
|
||||
code_addr : in std_logic_vector(15 downto 0);
|
||||
code_out : out std_logic_vector(15 downto 0);
|
||||
|
||||
data_addr : in std_logic_vector(15 downto 0);
|
||||
data_out : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end boot_rom;
|
||||
|
||||
architecture Behavioral of boot_rom is
|
||||
constant alignment: positive := busWidth / 8;
|
||||
constant romsize: natural := 92;
|
||||
|
||||
type romtype is array(0 to romsize - 1) of std_logic_vector(15 downto 0);
|
||||
signal romdata: romtype := (
|
||||
|
||||
x"ec00",
|
||||
x"9c11",
|
||||
x"e28c",
|
||||
x"e302",
|
||||
x"3de3",
|
||||
x"5e22",
|
||||
x"5eee",
|
||||
x"e012",
|
||||
x"90c0",
|
||||
x"e102",
|
||||
x"1000",
|
||||
x"6201",
|
||||
x"e100",
|
||||
x"4021",
|
||||
x"5edd",
|
||||
x"e012",
|
||||
x"90c0",
|
||||
x"e101",
|
||||
x"1000",
|
||||
x"6201",
|
||||
x"e100",
|
||||
x"4021",
|
||||
x"5edd",
|
||||
x"2dcf",
|
||||
x"e404",
|
||||
x"4cc4",
|
||||
x"e11e",
|
||||
x"20c0",
|
||||
x"e002",
|
||||
x"3de0",
|
||||
x"5e11",
|
||||
x"e200",
|
||||
x"c200",
|
||||
x"fe02",
|
||||
x"e101",
|
||||
x"e000",
|
||||
x"c010",
|
||||
x"de06",
|
||||
x"10c0",
|
||||
x"c000",
|
||||
x"dee2",
|
||||
x"e010",
|
||||
x"90c0",
|
||||
x"12c0",
|
||||
x"2200",
|
||||
x"e204",
|
||||
x"3cc2",
|
||||
x"1ecf",
|
||||
x"2dcf",
|
||||
x"e402",
|
||||
x"4cc4",
|
||||
x"e00e",
|
||||
x"e102",
|
||||
x"3de1",
|
||||
x"5e00",
|
||||
x"e200",
|
||||
x"c200",
|
||||
x"fe02",
|
||||
x"e101",
|
||||
x"e000",
|
||||
x"c010",
|
||||
x"de04",
|
||||
x"c000",
|
||||
x"dee6",
|
||||
x"e010",
|
||||
x"90c0",
|
||||
x"1000",
|
||||
x"e202",
|
||||
x"3cc2",
|
||||
x"1ecf",
|
||||
x"2dcf",
|
||||
x"e404",
|
||||
x"4cc4",
|
||||
x"e001",
|
||||
x"e100",
|
||||
x"c100",
|
||||
x"de16",
|
||||
x"e160",
|
||||
x"e002",
|
||||
x"3de0",
|
||||
x"5e11",
|
||||
x"e12e",
|
||||
x"20c0",
|
||||
x"e202",
|
||||
x"3de2",
|
||||
x"5e11",
|
||||
x"c000",
|
||||
x"dee2",
|
||||
x"e000",
|
||||
x"e104",
|
||||
x"3cc1",
|
||||
x"1ecf"
|
||||
|
||||
);
|
||||
begin
|
||||
|
||||
process(clk) is
|
||||
variable code_index: natural;
|
||||
variable data_index: natural;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
code_index := to_integer(unsigned(code_addr)) / alignment;
|
||||
if code_index < romsize then
|
||||
code_out <= romdata(code_index);
|
||||
else
|
||||
code_out <= x"0000";
|
||||
end if;
|
||||
|
||||
data_index := to_integer(unsigned(data_addr)) / alignment;
|
||||
data_out <= romdata(data_index);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
31
first/cc/blinky.c
Normal file
31
first/cc/blinky.c
Normal file
@@ -0,0 +1,31 @@
|
||||
// let's write blinky.c
|
||||
|
||||
#define LED_ADDR ((volatile char*)0xC000)
|
||||
|
||||
#define led_write(x) (*LED_ADDR = (x))
|
||||
|
||||
#define CYCLES_PER_MS 6666 // ish
|
||||
|
||||
void busy_sleep_1ms() {
|
||||
for (int i = 0; i < CYCLES_PER_MS; ++i) {
|
||||
// nothing
|
||||
}
|
||||
}
|
||||
|
||||
/** waits a general amount of time */
|
||||
void busy_sleep(int ms) {
|
||||
for (int i = 0; i < ms; ++i) {
|
||||
busy_sleep_1ms();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int onoff = 0;
|
||||
while (1) {
|
||||
led_write(onoff);
|
||||
busy_sleep(100);
|
||||
onoff++;
|
||||
}
|
||||
|
||||
return 0; // actually unreachable
|
||||
}
|
20
first/clock.vhdl
Normal file
20
first/clock.vhdl
Normal file
@@ -0,0 +1,20 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
entity clock is
|
||||
port ( clk: out std_logic);
|
||||
end clock;
|
||||
|
||||
architecture behaviour of clock
|
||||
is
|
||||
constant clk_period : time := 10 ns;
|
||||
begin
|
||||
-- Clock process definition
|
||||
clk_process: process
|
||||
begin
|
||||
clk <= '0';
|
||||
wait for clk_period/2;
|
||||
clk <= '1';
|
||||
wait for clk_period/2;
|
||||
end process;
|
||||
end behaviour;
|
197
first/cpu.vhdl
Normal file
197
first/cpu.vhdl
Normal file
@@ -0,0 +1,197 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity cpu is
|
||||
port(
|
||||
clk: in std_logic;
|
||||
rst: in std_logic;
|
||||
|
||||
code_data: in std_logic_vector(15 downto 0);
|
||||
code_addr: out std_logic_vector(15 downto 0);
|
||||
|
||||
mem_in: in std_logic_vector(15 downto 0);
|
||||
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
|
||||
);
|
||||
end entity cpu;
|
||||
|
||||
architecture behavior of cpu is
|
||||
component alu is
|
||||
port(
|
||||
a: in std_logic_vector(15 downto 0);
|
||||
b: in std_logic_vector(15 downto 0);
|
||||
sel: in std_logic_vector(3 downto 0);
|
||||
|
||||
flag: out std_logic;
|
||||
q: out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component reg is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
|
||||
d : in std_logic_vector(15 downto 0);
|
||||
q : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal alu_a: std_logic_vector(15 downto 0);
|
||||
signal alu_b: std_logic_vector(15 downto 0);
|
||||
signal alu_q: std_logic_vector(15 downto 0);
|
||||
signal alu_sel: std_logic_vector(3 downto 0);
|
||||
signal alu_flag: std_logic;
|
||||
|
||||
signal load_reg_next, load_reg: std_logic_vector(15 downto 0);
|
||||
signal load_addr_next, load_addr: 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);
|
||||
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);
|
||||
|
||||
allregs:
|
||||
for i in 0 to 15 generate
|
||||
regx: reg port map(clk => clk, rst => rst, d => reg_d(i), q => reg_q(i));
|
||||
end generate allregs;
|
||||
|
||||
process(clk, rst)
|
||||
begin
|
||||
if rst = '1' then
|
||||
cpu_state <= BRANCH; -- wait a cycle at first
|
||||
elsif rising_edge(clk) then
|
||||
cpu_state <= cpu_state_next;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
code_addr <= reg_q(14);
|
||||
|
||||
process(code_data, reg_q, mem_in, 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;
|
||||
variable regn_2: natural;
|
||||
variable do_alu: std_logic;
|
||||
begin
|
||||
mem_write <= '0';
|
||||
mem_read <= '0';
|
||||
mem_addr <= x"0000";
|
||||
mem_out <= x"0000";
|
||||
|
||||
alu_sel <= "0000";
|
||||
alu_a <= x"0000";
|
||||
alu_b <= x"0000";
|
||||
|
||||
do_alu := '0';
|
||||
|
||||
for i in 0 to 15 loop
|
||||
reg_d(i) <= reg_q(i);
|
||||
end loop;
|
||||
|
||||
cpu_state_next <= RUN;
|
||||
|
||||
load_reg_next <= load_reg;
|
||||
load_addr_next <= load_addr;
|
||||
|
||||
case cpu_state is
|
||||
when RUN =>
|
||||
reg_d(14) <= std_logic_vector(unsigned(reg_q(14)) + 2);
|
||||
inst := code_data;
|
||||
when LOAD =>
|
||||
inst := x"0000"; -- NOP
|
||||
mem_addr <= load_addr; -- maintain this until we're done reading
|
||||
if load_reg(3 downto 0) = x"e" then
|
||||
cpu_state_next <= BRANCH;
|
||||
else
|
||||
reg_d(14) <= std_logic_vector(unsigned(reg_q(14)) + 2);
|
||||
end if;
|
||||
|
||||
regn_0 := to_integer(unsigned(load_reg(3 downto 0)));
|
||||
reg_d(regn_0) <= mem_in;
|
||||
when BRANCH =>
|
||||
inst := x"0000"; -- NOP
|
||||
reg_d(14) <= std_logic_vector(unsigned(reg_q(14)) + 2);
|
||||
end case;
|
||||
|
||||
regn_0 := to_integer(unsigned(inst(11 downto 8)));
|
||||
regn_1 := to_integer(unsigned(inst(7 downto 4)));
|
||||
regn_2 := to_integer(unsigned(inst(3 downto 0)));
|
||||
|
||||
case inst(15 downto 12) is
|
||||
when "0000" => -- NOP
|
||||
when "0001" => -- LOAD rn, [rm, imm] (imm is signed 4 bits)
|
||||
mem_read <= '1';
|
||||
cpu_state_next <= LOAD;
|
||||
reg_d(14) <= reg_q(14); -- halt the prefetcher
|
||||
|
||||
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);
|
||||
when "0010" => -- STORE rn, [rm, imm]
|
||||
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);
|
||||
|
||||
--- ALU stuff
|
||||
when "0011" => do_alu := '1'; -- ADD rd, rn, rm (rd := rn + rm)
|
||||
when "0100" => do_alu := '1'; -- SUB rd, rn, rm (rd := rn - rm)
|
||||
when "0101" => do_alu := '1'; -- OR rd, rn, rm (rd := rn or rm)
|
||||
when "0110" => do_alu := '1'; -- AND rd, rn, rm (rd := rn and rm)
|
||||
when "0111" => do_alu := '1'; -- NOT rd, rn (rd := not rn)
|
||||
when "1000" => do_alu := '1'; -- XOR rd, rn, rm (rd := rn xor rm)
|
||||
when "1001" => -- SETH rd, imm
|
||||
reg_d(regn_0)(15 downto 8) <= inst(7 downto 0);
|
||||
when "1010" => -- SHR rd, rn, imm (rd := rn >> imm)
|
||||
alu_sel <= inst(15 downto 12);
|
||||
alu_a <= reg_q(regn_1);
|
||||
alu_b <= x"000" & inst(3 downto 0);
|
||||
reg_d(regn_0) <= alu_q;
|
||||
when "1011" => do_alu := '1'; -- MUL rd, rn, rm (rd := rn * rm)
|
||||
|
||||
when "1100" => -- CMP rn, rm (flag := 1 if equal)
|
||||
alu_sel <= "1100";
|
||||
alu_a <= reg_q(regn_0);
|
||||
alu_b <= reg_q(regn_1);
|
||||
reg_d(15)(0) <= alu_flag;
|
||||
|
||||
when "1101" => -- BEQ [rn, imm] (jump to [rn, imm] if flag is set, imm is signed 8 bits)
|
||||
if reg_q(15)(0) = '1' then
|
||||
reg_d(14) <= std_logic_vector(signed(reg_q(regn_0)) + signed(inst(7 downto 0)));
|
||||
cpu_state_next <= BRANCH;
|
||||
end if;
|
||||
when "1110" => -- SET rd, imm (rd := imm, imm is 8 bit)
|
||||
reg_d(regn_0) <= x"00" & inst(7 downto 0);
|
||||
when "1111" => -- BNEQ [rn, imm]
|
||||
if reg_q(15)(0) = '0' then
|
||||
reg_d(14) <= std_logic_vector(signed(reg_q(regn_0)) + signed(inst(7 downto 0)));
|
||||
cpu_state_next <= BRANCH;
|
||||
end if;
|
||||
|
||||
when others => -- do nothing
|
||||
end case;
|
||||
|
||||
if do_alu = '1' then
|
||||
-- 1:1 mapping
|
||||
alu_sel <= inst(15 downto 12);
|
||||
alu_a <= reg_q(regn_1);
|
||||
alu_b <= reg_q(regn_2);
|
||||
reg_d(regn_0) <= alu_q;
|
||||
reg_d(15)(0) <= alu_flag;
|
||||
if inst(11 downto 8) = x"e" then
|
||||
cpu_state_next <= BRANCH;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
147
first/cpu_test.vhdl
Normal file
147
first/cpu_test.vhdl
Normal file
@@ -0,0 +1,147 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity test_rom is
|
||||
generic
|
||||
(
|
||||
addressWidth : in positive := 16;
|
||||
busWidth : in positive := 16
|
||||
);
|
||||
port
|
||||
(
|
||||
address : in std_logic_vector(addressWidth - 1 downto 0);
|
||||
dataOut : out std_logic_vector(busWidth - 1 downto 0)
|
||||
);
|
||||
end test_rom;
|
||||
|
||||
architecture Behavioral of test_rom is
|
||||
constant alignment: positive := busWidth / 8;
|
||||
|
||||
--- type romtype is array(0 to 14) of std_logic_vector(15 downto 0);
|
||||
--- signal romdata: romtype := (
|
||||
---x"e180",
|
||||
---x"e200",
|
||||
---x"e301",
|
||||
---x"e4ff",
|
||||
---x"2210",
|
||||
---x"3223",
|
||||
---x"ed08",
|
||||
---x"ea00",
|
||||
---x"eb00",
|
||||
---x"3aa3",
|
||||
---x"fefe",
|
||||
---x"3bb3",
|
||||
---x"c0b4",
|
||||
---x"fef8",
|
||||
---x"ee08"
|
||||
---);
|
||||
|
||||
type romtype is array(0 to 10) of std_logic_vector(15 downto 0);
|
||||
signal romdata: romtype := (
|
||||
x"0000", -- NOP
|
||||
x"e02a", -- SET r0, 42
|
||||
x"e125", -- SET r1, 37
|
||||
x"2010", -- STORE r0, [r1]
|
||||
x"1210", -- LOAD r2, [r1]
|
||||
x"3322", -- ADD r3, r2, r2
|
||||
x"2310", -- STORE r3, [r1]
|
||||
x"c020", -- CMP r0, r2
|
||||
x"de04", -- BEQ pc, 4
|
||||
x"0000", -- NOP
|
||||
x"ee00" -- SET pc, 0
|
||||
);
|
||||
begin
|
||||
|
||||
process(address) is
|
||||
variable index: natural;
|
||||
begin
|
||||
index := to_integer(unsigned(address)) / alignment;
|
||||
dataOut <= romdata(index);
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
||||
|
||||
---
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity cpu_test is
|
||||
end cpu_test;
|
||||
|
||||
architecture rtl of cpu_test is
|
||||
|
||||
component clock is port(clk: out std_logic);
|
||||
end component;
|
||||
|
||||
component cpu is port(
|
||||
clk: in std_logic;
|
||||
rst: in std_logic;
|
||||
|
||||
code_data: in std_logic_vector(15 downto 0);
|
||||
code_addr: out std_logic_vector(15 downto 0);
|
||||
|
||||
mem_in: in std_logic_vector(15 downto 0);
|
||||
mem_out: out std_logic_vector(15 downto 0);
|
||||
mem_addr: out std_logic_vector(15 downto 0);
|
||||
mem_write: out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component test_rom is port (
|
||||
address : in std_logic_vector(15 downto 0);
|
||||
dataOut : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal clk, rst, mem_write: std_logic;
|
||||
signal rom_data, rom_addr, mem_in, mem_out, mem_addr: std_logic_vector(15 downto 0);
|
||||
|
||||
begin
|
||||
heartbeat: clock port map(clk);
|
||||
dut: cpu port map(clk, rst, rom_data, rom_addr, mem_in, mem_out, mem_addr, mem_write);
|
||||
rom: test_rom port map(rom_addr, rom_data);
|
||||
|
||||
process
|
||||
begin
|
||||
rst <= '1';
|
||||
|
||||
wait for 1 ns;
|
||||
assert(rom_addr=x"0000") report "Fail rst" severity error;
|
||||
|
||||
rst <= '0';
|
||||
|
||||
wait for 10 ns;
|
||||
assert(rom_addr=x"0002") report "Fail PC advance @00" severity error;
|
||||
|
||||
wait for 20 ns;
|
||||
assert(rom_addr=x"0006") report "Fail PC @06" severity error;
|
||||
assert(mem_write='1') report "Fail set mem_write to 1" severity error;
|
||||
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;
|
||||
|
||||
wait for 10 ns;
|
||||
assert(rom_addr=x"0008") report "Fail PC @08" severity error;
|
||||
assert(mem_write='0') report "Fail set mem_write to 0" severity error;
|
||||
assert(mem_addr=x"0025") report "Fail set mem_addr to 0x25" severity error;
|
||||
mem_in <= x"002a";
|
||||
|
||||
wait for 20 ns;
|
||||
assert(rom_addr=x"000c") report "Fail PC @0c" severity error;
|
||||
assert(mem_write='1') report "Fail set mem_write to 1" severity error;
|
||||
assert(mem_addr=x"0025") report "Fail set mem_addr to 0x25" severity error;
|
||||
assert(mem_out=x"0054") report "Fail set mem_out to 84" severity error;
|
||||
|
||||
wait for 30 ns;
|
||||
assert(rom_addr=x"0014") report "Fail to branch" severity error;
|
||||
|
||||
wait for 10 ns;
|
||||
assert(rom_addr=x"0000") report "Fail to jump" severity error;
|
||||
|
||||
assert false report "Test done." severity note;
|
||||
wait;
|
||||
end process;
|
||||
end rtl;
|
26
first/dff.vhdl
Normal file
26
first/dff.vhdl
Normal file
@@ -0,0 +1,26 @@
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
entity dff is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
|
||||
d : in std_logic;
|
||||
q : out std_logic
|
||||
);
|
||||
end entity dff;
|
||||
|
||||
architecture behavior of dff is
|
||||
begin
|
||||
process(clk, rst) is
|
||||
begin
|
||||
if (rst = '1') then
|
||||
q <= '0';
|
||||
else
|
||||
if rising_edge(clk) then
|
||||
q <= d;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end architecture behavior;
|
59
first/dff_test.vhdl
Normal file
59
first/dff_test.vhdl
Normal file
@@ -0,0 +1,59 @@
|
||||
-- Simple OR gate design
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity dff_test is
|
||||
end dff_test;
|
||||
|
||||
architecture rtl of dff_test is
|
||||
|
||||
component clock is
|
||||
port(clk: out std_logic);
|
||||
end component;
|
||||
|
||||
component dff is
|
||||
port(
|
||||
clk: in std_logic;
|
||||
rst: in std_logic;
|
||||
|
||||
d: in std_logic;
|
||||
q: out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal d, q, clk, rst: std_logic;
|
||||
|
||||
begin
|
||||
heartbeat: clock port map(clk);
|
||||
dut: dff port map(clk, rst, d, q);
|
||||
|
||||
process
|
||||
begin
|
||||
rst <= '1';
|
||||
|
||||
wait for 10 ns;
|
||||
assert(q='0') report "Fail rst" severity error;
|
||||
|
||||
rst <= '0';
|
||||
d <= '1';
|
||||
wait for 10 ns;
|
||||
assert(q='1') report "Fail d=1" severity error;
|
||||
|
||||
rst <= '1';
|
||||
wait for 1 ns;
|
||||
assert(q='0') report "Async rst fail" severity error;
|
||||
rst <= '0';
|
||||
d <= '1';
|
||||
wait for 9 ns;
|
||||
|
||||
d <= '0';
|
||||
wait for 1 ns;
|
||||
assert(q='1') report "Fail clk sync" severity error;
|
||||
wait for 9 ns;
|
||||
assert(q='0') report "Fail d=0" severity error;
|
||||
|
||||
assert false report "Test done." severity note;
|
||||
wait;
|
||||
end process;
|
||||
end rtl;
|
191
first/hello.vhdl
Normal file
191
first/hello.vhdl
Normal file
@@ -0,0 +1,191 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity hello is
|
||||
port(
|
||||
clk: in std_logic;
|
||||
rst: in std_logic;
|
||||
|
||||
led: out std_logic_vector(7 downto 0);
|
||||
|
||||
uart_rx: in std_logic;
|
||||
uart_tx: out std_logic
|
||||
);
|
||||
end hello;
|
||||
|
||||
architecture rtl of hello is
|
||||
|
||||
component cpu is port(
|
||||
clk: in std_logic;
|
||||
rst: in std_logic;
|
||||
|
||||
code_data: in std_logic_vector(15 downto 0);
|
||||
code_addr: out std_logic_vector(15 downto 0);
|
||||
|
||||
mem_in: in std_logic_vector(15 downto 0);
|
||||
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
|
||||
);
|
||||
end component;
|
||||
|
||||
-- component boot_rom IS
|
||||
-- PORT (
|
||||
-- clka : IN STD_LOGIC;
|
||||
-- addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
-- douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
|
||||
-- clkb : IN STD_LOGIC;
|
||||
-- addrb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
-- doutb : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
|
||||
-- );
|
||||
-- END component;
|
||||
|
||||
|
||||
--COMPONENT ram_mem
|
||||
-- PORT (
|
||||
-- clka : IN STD_LOGIC;
|
||||
-- wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
|
||||
-- addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
|
||||
-- dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
|
||||
-- douta : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
|
||||
-- );
|
||||
--END COMPONENT;
|
||||
|
||||
component ram is
|
||||
generic (
|
||||
addressWidth : in positive := 16;
|
||||
busWidth : in positive := 16;
|
||||
size : in positive := 1024
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
address : in std_logic_vector(addressWidth - 1 downto 0);
|
||||
writeEnable : in std_logic;
|
||||
dataIn : in std_logic_vector(busWidth - 1 downto 0);
|
||||
dataOut : out std_logic_vector(busWidth - 1 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component boot_rom is port (
|
||||
clk: in std_logic;
|
||||
|
||||
code_addr : in std_logic_vector(15 downto 0);
|
||||
code_out : out std_logic_vector(15 downto 0);
|
||||
|
||||
data_addr : in std_logic_vector(15 downto 0);
|
||||
data_out : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component uart is
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
|
||||
-- hardware
|
||||
rx_pin : in std_logic;
|
||||
tx_pin : out std_logic;
|
||||
|
||||
-- bus interface
|
||||
we : in std_logic;
|
||||
re : in std_logic;
|
||||
addr : in std_logic_vector(15 downto 0);
|
||||
din : in std_logic_vector(15 downto 0);
|
||||
dout : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal mem_write, mem_read: std_logic;
|
||||
signal rom_code_addr, rom_code_out, mem_in, mem_out, mem_addr: std_logic_vector(15 downto 0);
|
||||
signal rom_data_addr, rom_data_out: std_logic_vector(15 downto 0);
|
||||
|
||||
signal uart_din, uart_dout, uart_addr: std_logic_vector(15 downto 0);
|
||||
signal uart_we, uart_re: std_logic;
|
||||
|
||||
signal bus_write, bus_read: std_logic;
|
||||
signal bus_mosi, bus_miso, bus_addr: std_logic_vector(15 downto 0);
|
||||
|
||||
signal led_r, led_next: std_logic_vector(7 downto 0);
|
||||
|
||||
begin
|
||||
cpu0: cpu port map(clk, rst, rom_code_out, rom_code_addr, bus_miso, bus_mosi, bus_addr, bus_write, bus_read);
|
||||
-- rom: boot_rom port map(
|
||||
-- clka => clk, addra => rom_code_addr(8 downto 1), douta => rom_code_out,
|
||||
-- clkb => clk, addrb => rom_data_addr(8 downto 1), doutb => rom_data_out
|
||||
-- );
|
||||
-- mem: ram_mem port map(clka => clk, wea(0) => mem_write, addra => mem_addr(8 downto 1), dina => mem_in, douta => mem_out);
|
||||
rom: boot_rom port map(clk => clk, code_addr => rom_code_addr, code_out => rom_code_out,
|
||||
data_addr => rom_data_addr, data_out => rom_data_out);
|
||||
mem: ram port map(clk => clk, address => mem_addr, writeEnable => mem_write, dataIn => mem_in, dataOut => mem_out);
|
||||
|
||||
uart0: uart port map(clk => clk, rst => rst, rx_pin => uart_rx, tx_pin => uart_tx,
|
||||
addr => uart_addr, din => uart_din, dout => uart_dout, re => uart_re, we => uart_we);
|
||||
|
||||
-- system map
|
||||
-- 0x0000 - 0x0fff ROM
|
||||
-- 0x1000 - 0x1fff RAM
|
||||
-- 0xc000 - 0xc000 GPIO?
|
||||
|
||||
led <= led_r;
|
||||
|
||||
process(clk, rst)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
led_r <= led_next;
|
||||
end if;
|
||||
|
||||
if rst = '1' then
|
||||
led_r <= x"00";
|
||||
end if;
|
||||
end process;
|
||||
|
||||
process(bus_addr, bus_mosi, bus_write, mem_out, rst, rom_data_out, led_r, bus_read)
|
||||
begin
|
||||
|
||||
bus_miso <= x"0000";
|
||||
|
||||
rom_data_addr <= x"0000";
|
||||
|
||||
mem_addr <= x"0000";
|
||||
mem_in <= x"0000";
|
||||
mem_write <= '0';
|
||||
|
||||
led_next <= led_r;
|
||||
|
||||
uart_din <= x"0000";
|
||||
uart_addr <= x"0000";
|
||||
uart_we <= '0';
|
||||
uart_re <= '0';
|
||||
|
||||
case bus_addr(15 downto 12) is
|
||||
when x"0" =>
|
||||
bus_miso <= rom_data_out;
|
||||
rom_data_addr <= bus_addr and x"0fff";
|
||||
when x"1" =>
|
||||
mem_in <= bus_mosi;
|
||||
bus_miso <= mem_out;
|
||||
mem_addr <= bus_addr and x"0fff";
|
||||
mem_write <= bus_write;
|
||||
when x"c" =>
|
||||
case bus_addr(7 downto 4) is
|
||||
when x"0" => -- LED
|
||||
if bus_write = '1' then
|
||||
led_next <= bus_mosi(7 downto 0);
|
||||
end if;
|
||||
when x"1" => -- UART
|
||||
uart_din <= bus_mosi;
|
||||
bus_miso <= uart_dout;
|
||||
uart_addr <= bus_addr and x"000f";
|
||||
uart_we <= bus_write;
|
||||
uart_re <= bus_read;
|
||||
when others =>
|
||||
end case;
|
||||
when others =>
|
||||
end case;
|
||||
end process;
|
||||
|
||||
end rtl;
|
15
first/or.vhdl
Normal file
15
first/or.vhdl
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Simple OR gate design
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
|
||||
entity or_gate is
|
||||
port(
|
||||
a: in std_logic;
|
||||
b: in std_logic;
|
||||
q: out std_logic);
|
||||
end or_gate;
|
||||
|
||||
architecture rtl of or_gate is
|
||||
begin
|
||||
q <= a or b;
|
||||
end rtl;
|
54
first/or_test.vhdl
Normal file
54
first/or_test.vhdl
Normal file
@@ -0,0 +1,54 @@
|
||||
-- Simple OR gate design
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity or_test is
|
||||
end or_test;
|
||||
|
||||
architecture rtl of or_test is
|
||||
|
||||
component or_gate is
|
||||
port(
|
||||
a: in std_logic;
|
||||
b: in std_logic;
|
||||
q: out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal a_in, b_in, q_out: std_logic;
|
||||
|
||||
begin
|
||||
dut: or_gate port map(a_in, b_in, q_out);
|
||||
|
||||
process
|
||||
begin
|
||||
|
||||
a_in <= '0';
|
||||
b_in <= '0';
|
||||
wait for 1 ns;
|
||||
assert(q_out='0') report "Fail 0/0" severity error;
|
||||
|
||||
a_in <= '0';
|
||||
b_in <= '1';
|
||||
wait for 1 ns;
|
||||
assert(q_out='1') report "Fail 0/1" severity error;
|
||||
|
||||
a_in <= '1';
|
||||
b_in <= 'X';
|
||||
wait for 1 ns;
|
||||
assert(q_out='1') report "Fail 1/X" severity error;
|
||||
|
||||
a_in <= '1';
|
||||
b_in <= '1';
|
||||
wait for 1 ns;
|
||||
assert(q_out='1') report "Fail 1/1" severity error;
|
||||
|
||||
-- Clear inputs
|
||||
a_in <= '0';
|
||||
b_in <= '0';
|
||||
|
||||
assert false report "Test done." severity note;
|
||||
wait;
|
||||
end process;
|
||||
end rtl;
|
49
first/ram.vhdl
Normal file
49
first/ram.vhdl
Normal file
@@ -0,0 +1,49 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
-- Aligned IO only.
|
||||
-- Unaligned address bits are ignored.
|
||||
-- E.g. on a 16-bit bus, last address bit is ignored.
|
||||
entity ram is
|
||||
generic
|
||||
(
|
||||
addressWidth : in positive := 16;
|
||||
busWidth : in positive := 16;
|
||||
size : in positive := 1024
|
||||
);
|
||||
port
|
||||
(
|
||||
clk : in std_logic;
|
||||
address : in std_logic_vector(addressWidth - 1 downto 0);
|
||||
writeEnable : in std_logic;
|
||||
dataIn : in std_logic_vector(busWidth - 1 downto 0);
|
||||
dataOut : out std_logic_vector(busWidth - 1 downto 0)
|
||||
);
|
||||
end ram;
|
||||
|
||||
architecture Behavioral of ram is
|
||||
constant alignment : positive := busWidth / 8;
|
||||
constant ramSize : positive := size / alignment;
|
||||
|
||||
type ramType is array(natural range <>) of std_logic_vector(busWidth - 1 downto 0);
|
||||
subtype ramRange is natural range 0 to ramSize;
|
||||
|
||||
signal mem : ramType(ramRange);
|
||||
begin
|
||||
process(clk)
|
||||
variable index : ramRange;
|
||||
begin
|
||||
if (rising_edge(clk))
|
||||
then
|
||||
index := to_integer(unsigned(address)) / alignment;
|
||||
|
||||
if (writeEnable = '1')
|
||||
then
|
||||
mem(index) <= dataIn;
|
||||
end if;
|
||||
|
||||
dataOut <= mem(index);
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
52
first/regfile.vhdl
Normal file
52
first/regfile.vhdl
Normal file
@@ -0,0 +1,52 @@
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity regfile is
|
||||
Port ( outregna: in std_logic_vector(3 downto 0);
|
||||
outregda: out std_logic_vector(15 downto 0);
|
||||
|
||||
outregnb: in std_logic_vector(3 downto 0);
|
||||
outregdb: out std_logic_vector(15 downto 0);
|
||||
|
||||
inregn: in std_logic_vector(3 downto 0);
|
||||
inregd: in std_logic_vector(15 downto 0);
|
||||
inwe: in std_logic;
|
||||
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC
|
||||
);
|
||||
end regfile;
|
||||
|
||||
architecture Behavioral of regfile is
|
||||
component reg is
|
||||
Port ( d : in STD_LOGIC_VECTOR (15 downto 0);
|
||||
q : out STD_LOGIC_VECTOR (15 downto 0);
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC);
|
||||
end component;
|
||||
|
||||
type regbank is array(0 to 15) of std_logic_vector(15 downto 0);
|
||||
signal regd: regbank;
|
||||
signal regq: regbank;
|
||||
begin
|
||||
|
||||
regs:
|
||||
for i in 0 to 15 generate
|
||||
regx: reg port map(d => regd(i), q => regq(i), rst => rst, clk => clk);
|
||||
end generate;
|
||||
|
||||
outregda <= regq(to_integer(unsigned(outregna)));
|
||||
outregdb <= regq(to_integer(unsigned(outregnb)));
|
||||
|
||||
process(inregn, inregd, regq, inwe)
|
||||
begin
|
||||
for i in 0 to 15 loop
|
||||
regd(i) <= regq(i);
|
||||
if inwe = '1' then
|
||||
regd(to_integer(unsigned(inregn))) <= inregd;
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
55
first/register.vhdl
Normal file
55
first/register.vhdl
Normal file
@@ -0,0 +1,55 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 02/13/2021 01:13:18 PM
|
||||
-- Design Name:
|
||||
-- Module Name: register - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool Versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
--use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if instantiating
|
||||
-- any Xilinx leaf cells in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity reg is
|
||||
Port ( d : in STD_LOGIC_VECTOR (15 downto 0);
|
||||
q : out STD_LOGIC_VECTOR (15 downto 0);
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC);
|
||||
end reg;
|
||||
|
||||
architecture Behavioral of reg is
|
||||
begin
|
||||
|
||||
process(clk, rst) is
|
||||
begin
|
||||
if (rst = '1') then
|
||||
q <= x"0000";
|
||||
else
|
||||
if rising_edge(clk) then
|
||||
q <= d;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
39
first/rom.vhdl
Normal file
39
first/rom.vhdl
Normal file
@@ -0,0 +1,39 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
-- Aligned IO only.
|
||||
-- Unaligned address bits are ignored.
|
||||
-- E.g. on a 16-bit bus, last address bit is ignored.
|
||||
entity rom is
|
||||
generic
|
||||
(
|
||||
addressWidth : in positive := 16;
|
||||
busWidth : in positive := 16
|
||||
);
|
||||
port
|
||||
(
|
||||
address : in unsigned(addressWidth - 1 downto 0);
|
||||
dataOut : out std_logic_vector(busWidth - 1 downto 0)
|
||||
);
|
||||
end rom;
|
||||
|
||||
architecture Behavioral of rom is
|
||||
constant alignment : positive := busWidth / 8;
|
||||
|
||||
type romtype is array(0 to 2) of std_logic_vector(15 downto 0);
|
||||
signal romdata: romtype := (
|
||||
x"0002",
|
||||
x"0004",
|
||||
x"0000"
|
||||
);
|
||||
begin
|
||||
|
||||
process(address) is
|
||||
variable index: natural;
|
||||
begin
|
||||
index := to_integer(unsigned(address)) / alignment;
|
||||
dataOut <= romdata(index);
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
66
first/rom_test.vhdl
Normal file
66
first/rom_test.vhdl
Normal file
@@ -0,0 +1,66 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use std.textio.all;
|
||||
|
||||
entity rom_test is
|
||||
end rom_test;
|
||||
|
||||
architecture rtl of rom_test is
|
||||
|
||||
component clock is
|
||||
port(clk: out std_logic);
|
||||
end component;
|
||||
|
||||
component dff is
|
||||
port(
|
||||
clk: in std_logic;
|
||||
rst: in std_logic;
|
||||
|
||||
d: in std_logic;
|
||||
q: out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
component rom is port (
|
||||
address : in unsigned(15 downto 0);
|
||||
dataOut : out std_logic_vector(15 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal clk, rst: std_logic;
|
||||
signal romout, regq: std_logic_vector(15 downto 0);
|
||||
signal addr: unsigned(15 downto 0);
|
||||
|
||||
begin
|
||||
heartbeat: clock port map(clk);
|
||||
dut: rom port map(addr, romout);
|
||||
|
||||
reg:
|
||||
for i in 15 downto 0 generate
|
||||
regx: dff port map(clk, rst, romout(i), regq(i));
|
||||
end generate reg;
|
||||
|
||||
process(regq) begin
|
||||
addr <=unsigned(regq);
|
||||
end process;
|
||||
|
||||
process
|
||||
begin
|
||||
rst <= '1';
|
||||
|
||||
wait for 1 ns;
|
||||
assert(regq(0)='0') report "Fail rst" severity error;
|
||||
|
||||
rst <= '0';
|
||||
|
||||
wait for 10 ns;
|
||||
assert(to_integer(unsigned(regq))=2) report "Fail rom read @0" severity error;
|
||||
|
||||
wait for 10 ns;
|
||||
assert(to_integer(unsigned(regq))=4) report "Fail rom read @2" severity error;
|
||||
|
||||
assert false report "Test done." severity note;
|
||||
wait;
|
||||
end process;
|
||||
end rtl;
|
73
first/top.vhdl
Normal file
73
first/top.vhdl
Normal file
@@ -0,0 +1,73 @@
|
||||
----------------------------------------------------------------------------------
|
||||
-- Company:
|
||||
-- Engineer:
|
||||
--
|
||||
-- Create Date: 02/13/2021 12:09:57 AM
|
||||
-- Design Name:
|
||||
-- Module Name: top - Behavioral
|
||||
-- Project Name:
|
||||
-- Target Devices:
|
||||
-- Tool Versions:
|
||||
-- Description:
|
||||
--
|
||||
-- Dependencies:
|
||||
--
|
||||
-- Revision:
|
||||
-- Revision 0.01 - File Created
|
||||
-- Additional Comments:
|
||||
--
|
||||
----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
--use IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
-- Uncomment the following library declaration if instantiating
|
||||
-- any Xilinx leaf cells in this code.
|
||||
--library UNISIM;
|
||||
--use UNISIM.VComponents.all;
|
||||
|
||||
entity top is
|
||||
Port ( clk : in STD_LOGIC;
|
||||
rst_n : in STD_LOGIC;
|
||||
led : out STD_LOGIC_VECTOR (7 downto 0);
|
||||
usb_rx: in std_logic;
|
||||
usb_tx: out std_logic
|
||||
);
|
||||
end top;
|
||||
|
||||
architecture Behavioral of top is
|
||||
component hello is port(
|
||||
clk: in std_logic;
|
||||
rst: in std_logic;
|
||||
|
||||
led: out std_logic_vector(7 downto 0);
|
||||
|
||||
uart_rx: in std_logic;
|
||||
uart_tx: out std_logic
|
||||
|
||||
);
|
||||
end component;
|
||||
|
||||
component reset_conditioner is port(
|
||||
clk: in std_logic;
|
||||
rin: in std_logic;
|
||||
rout: out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
signal rst, rstraw: std_logic;
|
||||
|
||||
begin
|
||||
|
||||
rstraw <= not rst_n;
|
||||
reset: reset_conditioner port map(clk => clk, rin => rstraw, rout => rst);
|
||||
stuff: hello port map(clk => clk, rst => rst, led => led,
|
||||
uart_rx => usb_rx, uart_tx => usb_tx);
|
||||
|
||||
|
||||
end Behavioral;
|
Reference in New Issue
Block a user