Share soc.vhdl between FPGA and sim

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
nia-debug
Benjamin Herrenschmidt 5 years ago
parent d21ef5836d
commit 3ac1dbc737

@ -12,7 +12,7 @@ all: $(all)
$(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
@ -41,6 +41,7 @@ simple_ram_behavioural.o: wishbone_types.o simple_ram_behavioural_helpers.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


@ -13,88 +13,23 @@ end core_tb;
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
@ -111,14 +46,4 @@ 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;

@ -55,7 +55,8 @@ begin
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,

@ -24,19 +24,23 @@ filesets:
- 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
@ -64,7 +68,7 @@ filesets:
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}
@ -72,7 +76,7 @@ targets:

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}
@ -80,7 +84,7 @@ targets:

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}
@ -88,14 +92,14 @@ targets:

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

@ -31,18 +31,30 @@ use work.sim_console.all;
--! 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);

@ -56,7 +68,7 @@ architecture behaviour of sim_uart is

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);
@ -71,42 +83,40 @@ begin
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,
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;

@ -7,10 +7,10 @@ library work;
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 (
@ -20,14 +20,14 @@ entity simple_ram_behavioural is
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)

@ -17,8 +17,8 @@ architecture behave of simple_ram_behavioural_tb is
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

@ -2,7 +2,10 @@ 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;


@ -12,7 +15,8 @@ entity soc is
generic (
MEMORY_SIZE : positive;
RAM_INIT_FILE : string;
RESET_LOW : boolean
RESET_LOW : boolean;
SIM : boolean
);
port(
rst : in std_ulogic;
@ -37,30 +41,35 @@ architecture behaviour of soc is
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;
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
wishbone_data_out => wishbone_dcore_out,
registers => registers,
terminate_out => terminate
);

-- Wishbone bus master arbiter & mux
@ -77,8 +86,7 @@ begin
);

-- Wishbone slaves address decoder & mux
slave_intercon: process(wb_master_out, wb_bram_out,
uart0_ack_out, uart0_dat_out)
slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
-- Selected slave
type slave_type is (SLAVE_UART,
SLAVE_MEMORY,
@ -98,22 +106,42 @@ begin
-- Wishbone muxing. Defaults:
wb_bram_in <= wb_master_out;
wb_bram_in.cyc <= '0';
uart0_cyc_in <= '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 =>
uart0_cyc_in <= wb_master_out.cyc;
wb_master_in.ack <= uart0_ack_out;
wb_master_in.dat <= x"00000000000000" & uart0_dat_out;
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
@ -123,22 +151,15 @@ begin
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
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
);
-- 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;
wb_uart0_out.dat <= x"00000000000000" & uart_dat8;

-- BRAM Memory slave
bram0: entity work.mw_soc_memory
Loading…
Cancel
Save