$(GHDL) -a $(GHDLFLAGS) $<
common.o: decode_types.o
-core_tb.o: common.o wishbone_types.o core.o simple_ram_behavioural.o sim_uart.o
+core_tb.o: common.o core.o soc.o
core.o: common.o wishbone_types.o fetch1.o fetch2.o decode1.o decode2.o register_file.o cr_file.o execute1.o execute2.o loadstore1.o loadstore2.o multiply.o writeback.o wishbone_arbiter.o
cr_file.o: common.o
crhelpers.o: common.o
wishbone_arbiter.o: wishbone_types.o
wishbone_types.o:
writeback.o: common.o
+soc.o: wishbone_types.o simple_ram_behavioural.o sim_uart.o
fpga/soc_reset_tb.o: fpga/soc_reset.o
architecture behave of core_tb is
signal clk, rst: std_logic;
- signal wishbone_dcore_in : wishbone_slave_out;
- signal wishbone_dcore_out : wishbone_master_out;
-
- signal wishbone_icore_in : wishbone_slave_out;
- signal wishbone_icore_out : wishbone_master_out;
-
- signal wishbone_core_in : wishbone_slave_out;
- signal wishbone_core_out : wishbone_master_out;
-
- signal wishbone_ram_in : wishbone_slave_out;
- signal wishbone_ram_out : wishbone_master_out;
-
- signal wishbone_uart_in : wishbone_slave_out;
- signal wishbone_uart_out : wishbone_master_out;
-
- signal registers : regfile;
- signal terminate : std_ulogic;
-
-- testbench signals
constant clk_period : time := 10 ns;
begin
- core_0: entity work.core
- generic map (SIM => true)
- port map (clk => clk, rst => rst,
- wishbone_insn_in => wishbone_icore_in,
- wishbone_insn_out => wishbone_icore_out,
- wishbone_data_in => wishbone_dcore_in,
- wishbone_data_out => wishbone_dcore_out,
- registers => registers, terminate_out => terminate);
-
- simple_ram_0: entity work.simple_ram_behavioural
- generic map ( filename => "simple_ram_behavioural.bin", size => 524288)
- port map (clk => clk, rst => rst, wishbone_in => wishbone_ram_out, wishbone_out => wishbone_ram_in);
-
- simple_uart_0: entity work.sim_uart
- port map ( clk => clk, reset => rst, wishbone_in => wishbone_uart_out, wishbone_out => wishbone_uart_in);
-
- wishbone_arbiter_0: entity work.wishbone_arbiter
- port map (clk => clk, rst => rst,
- wb1_in => wishbone_dcore_out, wb1_out => wishbone_dcore_in,
- wb2_in => wishbone_icore_out, wb2_out => wishbone_icore_in,
- wb_out => wishbone_core_out, wb_in => wishbone_core_in);
-
- bus_process: process(wishbone_core_out, wishbone_ram_in, wishbone_uart_in)
- -- Selected slave
- type slave_type is (SLAVE_UART, SLAVE_MEMORY, SLAVE_NONE);
- variable slave : slave_type;
- begin
- -- Simple address decoder
- slave := SLAVE_NONE;
- if wishbone_core_out.adr(31 downto 24) = x"00" then
- slave := SLAVE_MEMORY;
- elsif wishbone_core_out.adr(31 downto 24) = x"c0" then
- if wishbone_core_out.adr(15 downto 12) = x"2" then
- slave := SLAVE_UART;
- end if;
- end if;
-
- -- Wishbone muxing:
- -- Start with all master signals to all slaves, then override
- -- cyc and stb accordingly
- wishbone_ram_out <= wishbone_core_out;
- wishbone_uart_out <= wishbone_core_out;
- if slave = SLAVE_MEMORY then
- wishbone_core_in <= wishbone_ram_in;
- else
- wishbone_ram_out.cyc <= '0';
- wishbone_ram_out.stb <= '0';
- end if;
- if slave = SLAVE_UART then
- wishbone_core_in <= wishbone_uart_in;
- else
- wishbone_uart_out.cyc <= '0';
- wishbone_uart_out.stb <= '0';
- end if;
- if slave = SLAVE_NONE then
- wishbone_core_in.dat <= (others => '1');
- wishbone_core_in.ack <= wishbone_core_out.cyc and
- wishbone_core_out.stb;
- end if;
- end process;
+ soc0: entity work.soc
+ generic map(
+ SIM => true,
+ MEMORY_SIZE => 524288,
+ RAM_INIT_FILE => "simple_ram_behavioural.bin",
+ RESET_LOW => false
+ )
+ port map(
+ rst => rst,
+ system_clk => clk,
+ uart0_rxd => '0',
+ uart0_txd => open
+ );
clk_process: process
begin
rst <= '0';
wait;
end process;
-
- dump_registers: process(all)
- begin
- if terminate = '1' then
- loop_0: for i in 0 to 31 loop
- report "REG " & to_hstring(registers(i));
- end loop loop_0;
- assert false report "end of test" severity failure;
- end if;
- end process;
end;
+++ /dev/null
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.math_real.all;
-
-library work;
-use work.wishbone_types.all;
-
-
--- 0x00000000: Main memory (1 MB)
--- 0xc0002000: UART0 (for host communication)
-entity soc is
- generic (
- MEMORY_SIZE : positive;
- RAM_INIT_FILE : string;
- RESET_LOW : boolean
- );
- port(
- rst : in std_ulogic;
- system_clk : in std_logic;
-
- -- UART0 signals:
- uart0_txd : out std_logic;
- uart0_rxd : in std_logic
- );
-end entity soc;
-
-architecture behaviour of soc is
-
- -- Wishbone master signals:
- signal wishbone_dcore_in : wishbone_slave_out;
- signal wishbone_dcore_out : wishbone_master_out;
- signal wishbone_icore_in : wishbone_slave_out;
- signal wishbone_icore_out : wishbone_master_out;
-
- -- Wishbone master (output of arbiter):
- signal wb_master_in : wishbone_slave_out;
- signal wb_master_out : wishbone_master_out;
-
- -- UART0 signals:
- signal uart0_adr_in : std_logic_vector(11 downto 0);
- signal uart0_dat_in : std_logic_vector( 7 downto 0);
- signal uart0_dat_out : std_logic_vector( 7 downto 0);
- signal uart0_cyc_in : std_logic;
- signal uart0_stb_in : std_logic;
- signal uart0_we_in : std_logic;
- signal uart0_ack_out : std_logic;
-
- -- Main memory signals:
- signal wb_bram_in : wishbone_master_out;
- signal wb_bram_out : wishbone_slave_out;
- constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
-
-begin
-
- -- Processor core
- processor: entity work.core
- port map(
- clk => system_clk,
- rst => rst,
- wishbone_insn_in => wishbone_icore_in,
- wishbone_insn_out => wishbone_icore_out,
- wishbone_data_in => wishbone_dcore_in,
- wishbone_data_out => wishbone_dcore_out
- );
-
- -- Wishbone bus master arbiter & mux
- wishbone_arbiter_0: entity work.wishbone_arbiter
- port map(
- clk => system_clk,
- rst => rst,
- wb1_in => wishbone_dcore_out,
- wb1_out => wishbone_dcore_in,
- wb2_in => wishbone_icore_out,
- wb2_out => wishbone_icore_in,
- wb_out => wb_master_out,
- wb_in => wb_master_in
- );
-
- -- Wishbone slaves address decoder & mux
- slave_intercon: process(wb_master_out, wb_bram_out,
- uart0_ack_out, uart0_dat_out)
- -- Selected slave
- type slave_type is (SLAVE_UART,
- SLAVE_MEMORY,
- SLAVE_NONE);
- variable slave : slave_type;
- begin
- -- Simple address decoder
- slave := SLAVE_NONE;
- if wb_master_out.adr(63 downto 24) = x"0000000000" then
- slave := SLAVE_MEMORY;
- elsif wb_master_out.adr(63 downto 24) = x"00000000c0" then
- if wb_master_out.adr(15 downto 12) = x"2" then
- slave := SLAVE_UART;
- end if;
- end if;
-
- -- Wishbone muxing. Defaults:
- wb_bram_in <= wb_master_out;
- wb_bram_in.cyc <= '0';
- uart0_cyc_in <= '0';
- case slave is
- when SLAVE_MEMORY =>
- wb_bram_in.cyc <= wb_master_out.cyc;
- wb_master_in <= wb_bram_out;
- when SLAVE_UART =>
- uart0_cyc_in <= wb_master_out.cyc;
- wb_master_in.ack <= uart0_ack_out;
- wb_master_in.dat <= x"00000000000000" & uart0_dat_out;
- when others =>
- wb_master_in.dat <= (others => '1');
- wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
- end case;
- end process slave_intercon;
-
- -- UART0 wishbone slave
- uart0: entity work.pp_soc_uart
- generic map(
- FIFO_DEPTH => 32
- )
- port map(
- clk => system_clk,
- reset => rst,
- txd => uart0_txd,
- rxd => uart0_rxd,
- wb_adr_in => uart0_adr_in,
- wb_dat_in => uart0_dat_in,
- wb_dat_out => uart0_dat_out,
- wb_cyc_in => uart0_cyc_in,
- wb_stb_in => uart0_stb_in,
- wb_we_in => uart0_we_in,
- wb_ack_out => uart0_ack_out
- );
- -- Wire it up: XXX FIXME: Need a proper wb64->wb8 adapter that
- -- converts SELs into low address bits and muxes
- -- data accordingly (either that or rejects large
- -- cycles).
- uart0_adr_in <= wb_master_out.adr(uart0_adr_in'range);
- uart0_dat_in <= wb_master_out.dat(7 downto 0);
- uart0_we_in <= wb_master_out.we;
- uart0_stb_in <= wb_master_out.stb;
-
- -- BRAM Memory slave
- bram0: entity work.mw_soc_memory
- generic map(
- MEMORY_SIZE => MEMORY_SIZE,
- RAM_INIT_FILE => RAM_INIT_FILE
- )
- port map(
- clk => system_clk,
- rst => rst,
- wishbone_in => wb_bram_in,
- wishbone_out => wb_bram_out
- );
-
-end architecture behaviour;
generic map(
MEMORY_SIZE => MEMORY_SIZE,
RAM_INIT_FILE => RAM_INIT_FILE,
- RESET_LOW => RESET_LOW
+ RESET_LOW => RESET_LOW,
+ SIM => false
)
port map (
system_clk => system_clk,
- loadstore2.vhdl
- multiply.vhdl
- writeback.vhdl
- - wishbone_arbiter.vhdl
- insn_helpers.vhdl
- core.vhdl
file_type : vhdlSource-2008
soc:
+ files:
+ - wishbone_arbiter.vhdl
+ - soc.vhdl
+ file_type : vhdlSource-2008
+
+ fpga:
files:
- fpga/pp_fifo.vhd
- fpga/mw_soc_memory.vhdl
- fpga/soc_reset.vhdl
- fpga/pp_soc_uart.vhd
- fpga/pp_utilities.vhd
- - fpga/soc.vhdl
- fpga/toplevel.vhdl
- fpga/firmware.hex : {copyto : firmware.hex, file_type : user}
file_type : vhdlSource-2008
targets:
nexys_a7:
default_tool: vivado
- filesets: [core, nexys_a7, soc]
+ filesets: [core, nexys_a7, soc, fpga]
parameters : [memory_size, ram_init_file]
tools:
vivado: {part : xc7a100tcsg324-1}
nexys_video:
default_tool: vivado
- filesets: [core, nexys_video, soc]
+ filesets: [core, nexys_video, soc, fpga]
parameters : [memory_size, ram_init_file]
tools:
vivado: {part : xc7a200tsbg484-1}
arty_a7-35:
default_tool: vivado
- filesets: [core, arty_a7-35, soc]
+ filesets: [core, arty_a7-35, soc, fpga]
parameters : [memory_size, ram_init_file]
tools:
vivado: {part : xc7a35ticsg324-1L}
cmod_a7-35:
default_tool: vivado
- filesets: [core, cmod_a7-35, soc]
+ filesets: [core, cmod_a7-35, soc, fpga]
parameters : [memory_size, ram_init_file, reset_low=false]
tools:
vivado: {part : xc7a35tcpg236-1}
toplevel : toplevel
synth:
- filesets: [core]
+ filesets: [core, soc]
tools:
vivado: {pnr : none}
toplevel: core
--! enable register. The following bits are available:
--! - Bit 0: data received (receive buffer not empty)
--! - Bit 1: ready to send data (transmit buffer empty)
-entity sim_uart is
+entity pp_soc_uart is
+ generic(
+ FIFO_DEPTH : natural := 64 --Unused
+ );
port(
clk : in std_logic;
reset : in std_logic;
+ -- UART ports:
+ txd : out std_logic;
+ rxd : in std_logic;
+
-- Wishbone ports:
- wishbone_in : in wishbone_master_out;
- wishbone_out : out wishbone_slave_out
+ wb_adr_in : in std_logic_vector(11 downto 0);
+ wb_dat_in : in std_logic_vector( 7 downto 0);
+ wb_dat_out : out std_logic_vector( 7 downto 0);
+ wb_we_in : in std_logic;
+ wb_cyc_in : in std_logic;
+ wb_stb_in : in std_logic;
+ wb_ack_out : out std_logic
);
-end entity sim_uart;
+end entity pp_soc_uart;
-architecture behaviour of sim_uart is
+architecture behaviour of pp_soc_uart is
signal sample_clk_divisor : std_logic_vector(7 downto 0);
begin
- wishbone_out.ack <= wb_ack and wishbone_in.cyc and wishbone_in.stb;
+ wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in;
wishbone: process(clk)
variable sim_tmp : std_logic_vector(63 downto 0);
else
case wb_state is
when IDLE =>
- if wishbone_in.cyc = '1' and wishbone_in.stb = '1' then
- if wishbone_in.we = '1' then -- Write to register
- if wishbone_in.adr(11 downto 0) = x"000" then
- report "FOO !";
- sim_console_write(wishbone_in.dat);
- elsif wishbone_in.adr(11 downto 0) = x"018" then
- sample_clk_divisor <= wishbone_in.dat(7 downto 0);
- elsif wishbone_in.adr(11 downto 0) = x"020" then
- irq_recv_enable <= wishbone_in.dat(0);
- irq_tx_ready_enable <= wishbone_in.dat(1);
+ if wb_cyc_in = '1' and wb_stb_in = '1' then
+ if wb_we_in = '1' then -- Write to register
+ if wb_adr_in(11 downto 0) = x"000" then
+ sim_console_write(x"00000000000000" & wb_dat_in);
+ elsif wb_adr_in(11 downto 0) = x"018" then
+ sample_clk_divisor <= wb_dat_in;
+ elsif wb_adr_in(11 downto 0) = x"020" then
+ irq_recv_enable <= wb_dat_in(0);
+ irq_tx_ready_enable <= wb_dat_in(1);
end if;
wb_ack <= '1';
wb_state <= WRITE_ACK;
else -- Read from register
- if wishbone_in.adr(11 downto 0) = x"008" then
+ if wb_adr_in(11 downto 0) = x"008" then
sim_console_read(sim_tmp);
- wishbone_out.dat <= sim_tmp;
- elsif wishbone_in.adr(11 downto 0) = x"010" then
+ wb_dat_out <= sim_tmp(7 downto 0);
+ elsif wb_adr_in(11 downto 0) = x"010" then
sim_console_poll(sim_tmp);
- wishbone_out.dat <= x"000000000000000" & '0' &
- sim_tmp(0) & '1' & not sim_tmp(0);
- elsif wishbone_in.adr(11 downto 0) = x"018" then
- wishbone_out.dat <= x"00000000000000" & sample_clk_divisor;
- elsif wishbone_in.adr(11 downto 0) = x"020" then
- wishbone_out.dat <= (0 => irq_recv_enable,
- 1 => irq_tx_ready_enable,
- others => '0');
+ wb_dat_out <= "00000" & sim_tmp(0) & '1' & not sim_tmp(0);
+ elsif wb_adr_in(11 downto 0) = x"018" then
+ wb_dat_out <= sample_clk_divisor;
+ elsif wb_adr_in(11 downto 0) = x"020" then
+ wb_dat_out <= (0 => irq_recv_enable,
+ 1 => irq_tx_ready_enable,
+ others => '0');
else
- wishbone_out.dat <= (others => '0');
+ wb_dat_out <= (others => '0');
end if;
wb_ack <= '1';
wb_state <= READ_ACK;
end if;
end if;
when WRITE_ACK|READ_ACK =>
- if wishbone_in.stb = '0' then
+ if wb_stb_in = '0' then
wb_ack <= '0';
wb_state <= IDLE;
end if;
use work.wishbone_types.all;
use work.simple_ram_behavioural_helpers.all;
-entity simple_ram_behavioural is
+entity mw_soc_memory is
generic (
- FILENAME : string;
- SIZE : integer
+ RAM_INIT_FILE : string;
+ MEMORY_SIZE : integer
);
port (
wishbone_in : in wishbone_master_out;
wishbone_out : out wishbone_slave_out
);
-end simple_ram_behavioural;
+end mw_soc_memory;
-architecture behave of simple_ram_behavioural is
+architecture behave of mw_soc_memory is
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 => FILENAME, size => SIZE);
+ signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, size => MEMORY_SIZE);
signal reload : integer := 0;
begin
wishbone_process: process(clk)
signal w_in : wishbone_slave_out;
signal w_out : wishbone_master_out;
begin
- simple_ram_0: entity work.simple_ram_behavioural
- generic map ( filename => "simple_ram_behavioural_tb.bin", size => 16 )
+ 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
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.math_real.all;
+
+use std.textio.all;
+
+library work;
+use work.common.all;
+use work.wishbone_types.all;
+
+
+-- 0x00000000: Main memory (1 MB)
+-- 0xc0002000: UART0 (for host communication)
+entity soc is
+ generic (
+ MEMORY_SIZE : positive;
+ RAM_INIT_FILE : string;
+ RESET_LOW : boolean;
+ SIM : boolean
+ );
+ port(
+ rst : in std_ulogic;
+ system_clk : in std_logic;
+
+ -- UART0 signals:
+ uart0_txd : out std_logic;
+ uart0_rxd : in std_logic
+ );
+end entity soc;
+
+architecture behaviour of soc is
+
+ -- Wishbone master signals:
+ signal wishbone_dcore_in : wishbone_slave_out;
+ signal wishbone_dcore_out : wishbone_master_out;
+ signal wishbone_icore_in : wishbone_slave_out;
+ signal wishbone_icore_out : wishbone_master_out;
+
+ -- Wishbone master (output of arbiter):
+ signal wb_master_in : wishbone_slave_out;
+ signal wb_master_out : wishbone_master_out;
+
+ -- UART0 signals:
+ signal wb_uart0_in : wishbone_master_out;
+ signal wb_uart0_out : wishbone_slave_out;
+ signal uart_dat8 : std_logic_vector(7 downto 0);
+
+ -- Main memory signals:
+ signal wb_bram_in : wishbone_master_out;
+ signal wb_bram_out : wishbone_slave_out;
+ constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
+
+ -- Debug signals (used in SIM only)
+ signal registers : regfile;
+ signal terminate : std_ulogic;
+
+begin
+
+ -- Processor core
+ processor: entity work.core
+ generic map(
+ SIM => SIM
+ )
+ port map(
+ clk => system_clk,
+ rst => rst,
+ wishbone_insn_in => wishbone_icore_in,
+ wishbone_insn_out => wishbone_icore_out,
+ wishbone_data_in => wishbone_dcore_in,
+ wishbone_data_out => wishbone_dcore_out,
+ registers => registers,
+ terminate_out => terminate
+ );
+
+ -- Wishbone bus master arbiter & mux
+ wishbone_arbiter_0: entity work.wishbone_arbiter
+ port map(
+ clk => system_clk,
+ rst => rst,
+ wb1_in => wishbone_dcore_out,
+ wb1_out => wishbone_dcore_in,
+ wb2_in => wishbone_icore_out,
+ wb2_out => wishbone_icore_in,
+ wb_out => wb_master_out,
+ wb_in => wb_master_in
+ );
+
+ -- Wishbone slaves address decoder & mux
+ slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
+ -- Selected slave
+ type slave_type is (SLAVE_UART,
+ SLAVE_MEMORY,
+ SLAVE_NONE);
+ variable slave : slave_type;
+ begin
+ -- Simple address decoder
+ slave := SLAVE_NONE;
+ if wb_master_out.adr(63 downto 24) = x"0000000000" then
+ slave := SLAVE_MEMORY;
+ elsif wb_master_out.adr(63 downto 24) = x"00000000c0" then
+ if wb_master_out.adr(15 downto 12) = x"2" then
+ slave := SLAVE_UART;
+ end if;
+ end if;
+
+ -- Wishbone muxing. Defaults:
+ wb_bram_in <= wb_master_out;
+ wb_bram_in.cyc <= '0';
+ wb_uart0_in <= wb_master_out;
+ wb_uart0_in.cyc <= '0';
+ case slave is
+ when SLAVE_MEMORY =>
+ wb_bram_in.cyc <= wb_master_out.cyc;
+ wb_master_in <= wb_bram_out;
+ when SLAVE_UART =>
+ wb_uart0_in.cyc <= wb_master_out.cyc;
+ wb_master_in <= wb_uart0_out;
+ when others =>
+ wb_master_in.dat <= (others => '1');
+ wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
+ end case;
+ end process slave_intercon;
+
+ -- Simulated memory and UART
+ sim_terminate_test: if SIM generate
+
+ -- Dump registers if core terminates
+ dump_registers: process(all)
+ begin
+ if terminate = '1' then
+ loop_0: for i in 0 to 31 loop
+ report "REG " & to_hstring(registers(i));
+ end loop loop_0;
+ assert false report "end of test" severity failure;
+ end if;
+ end process;
+
+ end generate;
+
+ -- UART0 wishbone slave
+ -- XXX FIXME: Need a proper wb64->wb8 adapter that
+ -- converts SELs into low address bits and muxes
+ -- data accordingly (either that or rejects large
+ -- cycles).
+ uart0: entity work.pp_soc_uart
+ generic map(
+ FIFO_DEPTH => 32
+ )
+ port map(
+ clk => system_clk,
+ reset => rst,
+ txd => uart0_txd,
+ rxd => uart0_rxd,
+ wb_adr_in => wb_uart0_in.adr(11 downto 0),
+ wb_dat_in => wb_uart0_in.dat(7 downto 0),
+ wb_dat_out => uart_dat8,
+ wb_cyc_in => wb_uart0_in.cyc,
+ wb_stb_in => wb_uart0_in.stb,
+ wb_we_in => wb_uart0_in.we,
+ wb_ack_out => wb_uart0_out.ack
+ );
+ wb_uart0_out.dat <= x"00000000000000" & uart_dat8;
+
+ -- BRAM Memory slave
+ bram0: entity work.mw_soc_memory
+ generic map(
+ MEMORY_SIZE => MEMORY_SIZE,
+ RAM_INIT_FILE => RAM_INIT_FILE
+ )
+ port map(
+ clk => system_clk,
+ rst => rst,
+ wishbone_in => wb_bram_in,
+ wishbone_out => wb_bram_out
+ );
+
+end architecture behaviour;