Share soc.vhdl between FPGA and sim

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
pull/40/head
Benjamin Herrenschmidt 5 years ago
parent d21ef5836d
commit 3ac1dbc737

@ -12,7 +12,7 @@ all: $(all)
$(GHDL) -a $(GHDLFLAGS) $< $(GHDL) -a $(GHDLFLAGS) $<


common.o: decode_types.o 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 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 cr_file.o: common.o
crhelpers.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_arbiter.o: wishbone_types.o
wishbone_types.o: wishbone_types.o:
writeback.o: common.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 fpga/soc_reset_tb.o: fpga/soc_reset.o



@ -13,88 +13,23 @@ end core_tb;
architecture behave of core_tb is architecture behave of core_tb is
signal clk, rst: std_logic; 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 -- testbench signals
constant clk_period : time := 10 ns; constant clk_period : time := 10 ns;
begin 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);



soc0: entity work.soc
wishbone_arbiter_0: entity work.wishbone_arbiter generic map(
port map (clk => clk, rst => rst, SIM => true,
wb1_in => wishbone_dcore_out, wb1_out => wishbone_dcore_in, MEMORY_SIZE => 524288,
wb2_in => wishbone_icore_out, wb2_out => wishbone_icore_in, RAM_INIT_FILE => "simple_ram_behavioural.bin",
wb_out => wishbone_core_out, wb_in => wishbone_core_in); RESET_LOW => false

)
bus_process: process(wishbone_core_out, wishbone_ram_in, wishbone_uart_in) port map(
-- Selected slave rst => rst,
type slave_type is (SLAVE_UART, SLAVE_MEMORY, SLAVE_NONE); system_clk => clk,
variable slave : slave_type; uart0_rxd => '0',
begin uart0_txd => open
-- 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;


clk_process: process clk_process: process
begin begin
@ -111,14 +46,4 @@ begin
rst <= '0'; rst <= '0';
wait; wait;
end process; 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; end;

@ -55,7 +55,8 @@ begin
generic map( generic map(
MEMORY_SIZE => MEMORY_SIZE, MEMORY_SIZE => MEMORY_SIZE,
RAM_INIT_FILE => RAM_INIT_FILE, RAM_INIT_FILE => RAM_INIT_FILE,
RESET_LOW => RESET_LOW RESET_LOW => RESET_LOW,
SIM => false
) )
port map ( port map (
system_clk => system_clk, system_clk => system_clk,

@ -24,19 +24,23 @@ filesets:
- loadstore2.vhdl - loadstore2.vhdl
- multiply.vhdl - multiply.vhdl
- writeback.vhdl - writeback.vhdl
- wishbone_arbiter.vhdl
- insn_helpers.vhdl - insn_helpers.vhdl
- core.vhdl - core.vhdl
file_type : vhdlSource-2008 file_type : vhdlSource-2008


soc: soc:
files:
- wishbone_arbiter.vhdl
- soc.vhdl
file_type : vhdlSource-2008

fpga:
files: files:
- fpga/pp_fifo.vhd - fpga/pp_fifo.vhd
- fpga/mw_soc_memory.vhdl - fpga/mw_soc_memory.vhdl
- fpga/soc_reset.vhdl - fpga/soc_reset.vhdl
- fpga/pp_soc_uart.vhd - fpga/pp_soc_uart.vhd
- fpga/pp_utilities.vhd - fpga/pp_utilities.vhd
- fpga/soc.vhdl
- fpga/toplevel.vhdl - fpga/toplevel.vhdl
- fpga/firmware.hex : {copyto : firmware.hex, file_type : user} - fpga/firmware.hex : {copyto : firmware.hex, file_type : user}
file_type : vhdlSource-2008 file_type : vhdlSource-2008
@ -64,7 +68,7 @@ filesets:
targets: targets:
nexys_a7: nexys_a7:
default_tool: vivado default_tool: vivado
filesets: [core, nexys_a7, soc] filesets: [core, nexys_a7, soc, fpga]
parameters : [memory_size, ram_init_file] parameters : [memory_size, ram_init_file]
tools: tools:
vivado: {part : xc7a100tcsg324-1} vivado: {part : xc7a100tcsg324-1}
@ -72,7 +76,7 @@ targets:


nexys_video: nexys_video:
default_tool: vivado default_tool: vivado
filesets: [core, nexys_video, soc] filesets: [core, nexys_video, soc, fpga]
parameters : [memory_size, ram_init_file] parameters : [memory_size, ram_init_file]
tools: tools:
vivado: {part : xc7a200tsbg484-1} vivado: {part : xc7a200tsbg484-1}
@ -80,7 +84,7 @@ targets:


arty_a7-35: arty_a7-35:
default_tool: vivado default_tool: vivado
filesets: [core, arty_a7-35, soc] filesets: [core, arty_a7-35, soc, fpga]
parameters : [memory_size, ram_init_file] parameters : [memory_size, ram_init_file]
tools: tools:
vivado: {part : xc7a35ticsg324-1L} vivado: {part : xc7a35ticsg324-1L}
@ -88,14 +92,14 @@ targets:


cmod_a7-35: cmod_a7-35:
default_tool: vivado 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] parameters : [memory_size, ram_init_file, reset_low=false]
tools: tools:
vivado: {part : xc7a35tcpg236-1} vivado: {part : xc7a35tcpg236-1}
toplevel : toplevel toplevel : toplevel


synth: synth:
filesets: [core] filesets: [core, soc]
tools: tools:
vivado: {pnr : none} vivado: {pnr : none}
toplevel: core toplevel: core

@ -31,18 +31,30 @@ use work.sim_console.all;
--! enable register. The following bits are available: --! enable register. The following bits are available:
--! - Bit 0: data received (receive buffer not empty) --! - Bit 0: data received (receive buffer not empty)
--! - Bit 1: ready to send data (transmit buffer 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( port(
clk : in std_logic; clk : in std_logic;
reset : in std_logic; reset : in std_logic;


-- UART ports:
txd : out std_logic;
rxd : in std_logic;

-- Wishbone ports: -- Wishbone ports:
wishbone_in : in wishbone_master_out; wb_adr_in : in std_logic_vector(11 downto 0);
wishbone_out : out wishbone_slave_out 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); signal sample_clk_divisor : std_logic_vector(7 downto 0);


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


begin 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) wishbone: process(clk)
variable sim_tmp : std_logic_vector(63 downto 0); variable sim_tmp : std_logic_vector(63 downto 0);
@ -71,42 +83,40 @@ begin
else else
case wb_state is case wb_state is
when IDLE => when IDLE =>
if wishbone_in.cyc = '1' and wishbone_in.stb = '1' then if wb_cyc_in = '1' and wb_stb_in = '1' then
if wishbone_in.we = '1' then -- Write to register if wb_we_in = '1' then -- Write to register
if wishbone_in.adr(11 downto 0) = x"000" then if wb_adr_in(11 downto 0) = x"000" then
report "FOO !"; sim_console_write(x"00000000000000" & wb_dat_in);
sim_console_write(wishbone_in.dat); elsif wb_adr_in(11 downto 0) = x"018" then
elsif wishbone_in.adr(11 downto 0) = x"018" then sample_clk_divisor <= wb_dat_in;
sample_clk_divisor <= wishbone_in.dat(7 downto 0); elsif wb_adr_in(11 downto 0) = x"020" then
elsif wishbone_in.adr(11 downto 0) = x"020" then irq_recv_enable <= wb_dat_in(0);
irq_recv_enable <= wishbone_in.dat(0); irq_tx_ready_enable <= wb_dat_in(1);
irq_tx_ready_enable <= wishbone_in.dat(1);
end if; end if;
wb_ack <= '1'; wb_ack <= '1';
wb_state <= WRITE_ACK; wb_state <= WRITE_ACK;
else -- Read from register 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); sim_console_read(sim_tmp);
wishbone_out.dat <= sim_tmp; wb_dat_out <= sim_tmp(7 downto 0);
elsif wishbone_in.adr(11 downto 0) = x"010" then elsif wb_adr_in(11 downto 0) = x"010" then
sim_console_poll(sim_tmp); sim_console_poll(sim_tmp);
wishbone_out.dat <= x"000000000000000" & '0' & wb_dat_out <= "00000" & sim_tmp(0) & '1' & not sim_tmp(0);
sim_tmp(0) & '1' & not sim_tmp(0); elsif wb_adr_in(11 downto 0) = x"018" then
elsif wishbone_in.adr(11 downto 0) = x"018" then wb_dat_out <= sample_clk_divisor;
wishbone_out.dat <= x"00000000000000" & sample_clk_divisor; elsif wb_adr_in(11 downto 0) = x"020" then
elsif wishbone_in.adr(11 downto 0) = x"020" then wb_dat_out <= (0 => irq_recv_enable,
wishbone_out.dat <= (0 => irq_recv_enable, 1 => irq_tx_ready_enable,
1 => irq_tx_ready_enable, others => '0');
others => '0');
else else
wishbone_out.dat <= (others => '0'); wb_dat_out <= (others => '0');
end if; end if;
wb_ack <= '1'; wb_ack <= '1';
wb_state <= READ_ACK; wb_state <= READ_ACK;
end if; end if;
end if; end if;
when WRITE_ACK|READ_ACK => when WRITE_ACK|READ_ACK =>
if wishbone_in.stb = '0' then if wb_stb_in = '0' then
wb_ack <= '0'; wb_ack <= '0';
wb_state <= IDLE; wb_state <= IDLE;
end if; end if;

@ -7,10 +7,10 @@ library work;
use work.wishbone_types.all; use work.wishbone_types.all;
use work.simple_ram_behavioural_helpers.all; use work.simple_ram_behavioural_helpers.all;


entity simple_ram_behavioural is entity mw_soc_memory is
generic ( generic (
FILENAME : string; RAM_INIT_FILE : string;
SIZE : integer MEMORY_SIZE : integer
); );


port ( port (
@ -20,14 +20,14 @@ entity simple_ram_behavioural is
wishbone_in : in wishbone_master_out; wishbone_in : in wishbone_master_out;
wishbone_out : out wishbone_slave_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); type wishbone_state_t is (IDLE, ACK);


signal state : wishbone_state_t := IDLE; signal state : wishbone_state_t := IDLE;
signal ret_ack : std_ulogic := '0'; 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; signal reload : integer := 0;
begin begin
wishbone_process: process(clk) wishbone_process: process(clk)

@ -17,8 +17,8 @@ architecture behave of simple_ram_behavioural_tb is
signal w_in : wishbone_slave_out; signal w_in : wishbone_slave_out;
signal w_out : wishbone_master_out; signal w_out : wishbone_master_out;
begin begin
simple_ram_0: entity work.simple_ram_behavioural simple_ram_0: entity work.mw_soc_memory
generic map ( filename => "simple_ram_behavioural_tb.bin", size => 16 ) 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); port map (clk => clk, rst => rst, wishbone_out => w_in, wishbone_in => w_out);


clock: process clock: process

@ -2,7 +2,10 @@ library ieee;
use ieee.std_logic_1164.all; use ieee.std_logic_1164.all;
use ieee.math_real.all; use ieee.math_real.all;


use std.textio.all;

library work; library work;
use work.common.all;
use work.wishbone_types.all; use work.wishbone_types.all;




@ -12,7 +15,8 @@ entity soc is
generic ( generic (
MEMORY_SIZE : positive; MEMORY_SIZE : positive;
RAM_INIT_FILE : string; RAM_INIT_FILE : string;
RESET_LOW : boolean RESET_LOW : boolean;
SIM : boolean
); );
port( port(
rst : in std_ulogic; rst : in std_ulogic;
@ -37,30 +41,35 @@ architecture behaviour of soc is
signal wb_master_out : wishbone_master_out; signal wb_master_out : wishbone_master_out;


-- UART0 signals: -- UART0 signals:
signal uart0_adr_in : std_logic_vector(11 downto 0); signal wb_uart0_in : wishbone_master_out;
signal uart0_dat_in : std_logic_vector( 7 downto 0); signal wb_uart0_out : wishbone_slave_out;
signal uart0_dat_out : std_logic_vector( 7 downto 0); signal uart_dat8 : 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: -- Main memory signals:
signal wb_bram_in : wishbone_master_out; signal wb_bram_in : wishbone_master_out;
signal wb_bram_out : wishbone_slave_out; signal wb_bram_out : wishbone_slave_out;
constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE)))); 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 begin


-- Processor core -- Processor core
processor: entity work.core processor: entity work.core
generic map(
SIM => SIM
)
port map( port map(
clk => system_clk, clk => system_clk,
rst => rst, rst => rst,
wishbone_insn_in => wishbone_icore_in, wishbone_insn_in => wishbone_icore_in,
wishbone_insn_out => wishbone_icore_out, wishbone_insn_out => wishbone_icore_out,
wishbone_data_in => wishbone_dcore_in, 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 -- Wishbone bus master arbiter & mux
@ -77,8 +86,7 @@ begin
); );


-- Wishbone slaves address decoder & mux -- Wishbone slaves address decoder & mux
slave_intercon: process(wb_master_out, wb_bram_out, slave_intercon: process(wb_master_out, wb_bram_out, wb_uart0_out)
uart0_ack_out, uart0_dat_out)
-- Selected slave -- Selected slave
type slave_type is (SLAVE_UART, type slave_type is (SLAVE_UART,
SLAVE_MEMORY, SLAVE_MEMORY,
@ -98,22 +106,42 @@ begin
-- Wishbone muxing. Defaults: -- Wishbone muxing. Defaults:
wb_bram_in <= wb_master_out; wb_bram_in <= wb_master_out;
wb_bram_in.cyc <= '0'; wb_bram_in.cyc <= '0';
uart0_cyc_in <= '0'; wb_uart0_in <= wb_master_out;
wb_uart0_in.cyc <= '0';
case slave is case slave is
when SLAVE_MEMORY => when SLAVE_MEMORY =>
wb_bram_in.cyc <= wb_master_out.cyc; wb_bram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_bram_out; wb_master_in <= wb_bram_out;
when SLAVE_UART => when SLAVE_UART =>
uart0_cyc_in <= wb_master_out.cyc; wb_uart0_in.cyc <= wb_master_out.cyc;
wb_master_in.ack <= uart0_ack_out; wb_master_in <= wb_uart0_out;
wb_master_in.dat <= x"00000000000000" & uart0_dat_out;
when others => when others =>
wb_master_in.dat <= (others => '1'); wb_master_in.dat <= (others => '1');
wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc; wb_master_in.ack <= wb_master_out.stb and wb_master_out.cyc;
end case; end case;
end process slave_intercon; 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 -- 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 uart0: entity work.pp_soc_uart
generic map( generic map(
FIFO_DEPTH => 32 FIFO_DEPTH => 32
@ -123,22 +151,15 @@ begin
reset => rst, reset => rst,
txd => uart0_txd, txd => uart0_txd,
rxd => uart0_rxd, rxd => uart0_rxd,
wb_adr_in => uart0_adr_in, wb_adr_in => wb_uart0_in.adr(11 downto 0),
wb_dat_in => uart0_dat_in, wb_dat_in => wb_uart0_in.dat(7 downto 0),
wb_dat_out => uart0_dat_out, wb_dat_out => uart_dat8,
wb_cyc_in => uart0_cyc_in, wb_cyc_in => wb_uart0_in.cyc,
wb_stb_in => uart0_stb_in, wb_stb_in => wb_uart0_in.stb,
wb_we_in => uart0_we_in, wb_we_in => wb_uart0_in.we,
wb_ack_out => uart0_ack_out wb_ack_out => wb_uart0_out.ack
); );
-- Wire it up: XXX FIXME: Need a proper wb64->wb8 adapter that wb_uart0_out.dat <= x"00000000000000" & uart_dat8;
-- 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 -- BRAM Memory slave
bram0: entity work.mw_soc_memory bram0: entity work.mw_soc_memory
Loading…
Cancel
Save