diff --git a/Makefile b/Makefile index 631621f..02526e0 100644 --- a/Makefile +++ b/Makefile @@ -195,7 +195,7 @@ endif fpga_files = $(core_files) $(soc_files) fpga/soc_reset.vhdl \ fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram_caravel.vhdl \ - nonrandom.vhdl + nonrandom.vhdl mc.vhdl mc_pkg.vhdl synth_files = $(core_files) $(soc_files) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm) diff --git a/fpga/top-caravel.vhdl b/fpga/top-caravel.vhdl index 74939de..738fff1 100644 --- a/fpga/top-caravel.vhdl +++ b/fpga/top-caravel.vhdl @@ -50,17 +50,13 @@ entity toplevel is jtag_trst : in std_ulogic; jtag_tdo : out std_ulogic; - -- Wishbone over LA - wb_la_adr : out wishbone_addr_type; - wb_la_dat_o : out wishbone_data_type; - wb_la_cyc : out std_ulogic; - wb_la_stb : out std_ulogic; - wb_la_sel : out wishbone_sel_type; - wb_la_we : out std_ulogic; - - wb_la_dat_i : in wishbone_data_type; - wb_la_ack : in std_ulogic; - wb_la_stall : in std_ulogic + -- bills bus + oib_clk : out std_ulogic; + ob_data : out std_ulogic_vector(7 downto 0); + ob_pty : out std_ulogic; + + ib_data : in std_ulogic_vector(7 downto 0); + ib_pty : in std_ulogic -- XXX Add simple external bus @@ -77,10 +73,22 @@ architecture behaviour of toplevel is -- Internal clock signals: signal system_clk : std_ulogic; signal system_clk_locked : std_ulogic; + signal ext_rst_n : std_ulogic; -- wishbone over logic analyzer connection - signal wb_la_out : wishbone_master_out; - signal wb_la_in : wishbone_slave_out; + signal wb_dram_out : wishbone_master_out; + signal wb_dram_in : wishbone_slave_out; + + -- Wishbone over LA + signal wb_mc_adr : wishbone_addr_type; + signal wb_mc_dat_o : wishbone_data_type; + signal wb_mc_cyc : std_ulogic; + signal wb_mc_stb : std_ulogic; + signal wb_mc_sel : wishbone_sel_type; + signal wb_mc_we : std_ulogic; + signal wb_mc_dat_i : wishbone_data_type; + signal wb_mc_ack : std_ulogic; + signal wb_mc_stall : std_ulogic; -- SPI flash signal spi_sck : std_ulogic; @@ -139,11 +147,46 @@ begin jtag_trst => jtag_trst, jtag_tdo => jtag_tdo, - -- Use DRAM wishbone for wishbone over LA - wb_dram_in => wb_la_out, - wb_dram_out => wb_la_in + -- Use DRAM wishbone for Bill's bus + wb_dram_in => wb_dram_out, + wb_dram_out => wb_dram_in ); + ext_rst_n <= not ext_rst; + + mc0: entity work.mc + generic map( + WB_AW => 32, -- wishbone_addr_bits + WB_DW => 64, -- wishbone_data_bits + OIB_DW => 8, + OIB_RATIO => 2, -- bill said this + BAR_INIT => x"1fff" -- dram has 512 bit space. CPU gives + -- top 3 bits as 0. carve off small + -- chunk at top for config space. + ) + port map ( + clk => system_clk, + rst => ext_rst_n, + + wb_cyc => wb_mc_cyc, + wb_stb => wb_mc_stb, + wb_we => wb_mc_we, + wb_addr => wb_mc_adr, + wb_wr_data => wb_mc_dat_o, + wb_sel => wb_mc_sel, + wb_ack => wb_mc_ack, +-- wb_err => wb_mc_err, ?? + wb_stall => wb_mc_stall, + wb_rd_data => wb_mc_dat_i, + oib_clk => oib_clk, + ob_data => ob_data, + ob_pty => ob_pty, + ib_data => ib_data, + ib_pty => ib_pty +-- err => ob _err, +-- int => ob int + ); + -- SPI Flash spi_flash_cs_n <= spi_cs_n; spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z'; @@ -157,16 +200,16 @@ begin spi_flash_clk <= spi_sck; -- Wishbone over LA - wb_la_adr <= wb_la_out.adr; - wb_la_dat_o <= wb_la_out.dat; - wb_la_cyc <= wb_la_out.cyc; - wb_la_stb <= wb_la_out.stb; - wb_la_sel <= wb_la_out.sel; - wb_la_we <= wb_la_out.we; - - wb_la_in.dat <= wb_la_dat_i; - wb_la_in.ack <= wb_la_ack; - wb_la_in.stall <= wb_la_stall; + wb_mc_adr <= wb_dram_out.adr; + wb_mc_dat_o <= wb_dram_out.dat; + wb_mc_cyc <= wb_dram_out.cyc; + wb_mc_stb <= wb_dram_out.stb; + wb_mc_sel <= wb_dram_out.sel; + wb_mc_we <= wb_dram_out.we; + + wb_dram_in.dat <= wb_mc_dat_i; + wb_dram_in.ack <= wb_mc_ack; + wb_dram_in.stall <= wb_mc_stall; reset_controller: entity work.soc_reset generic map( diff --git a/mc.vhdl b/mc.vhdl new file mode 100644 index 0000000..cb59669 --- /dev/null +++ b/mc.vhdl @@ -0,0 +1,929 @@ +-- Wishbone slave to packet bus + +-- add way to reset (or do externally) +-- not obeying sel on local writes yet! +-- theoretically, this should work with slave-initiated packets like ints, even +-- if they intervene within a pending master command (unpreventable because of +-- concurrent xmits). + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; +use work.wishbone_types.all; +use work.mc_pkg.all; + +entity mc is + + generic( + WB_AW : integer := 32; -- wishbone_addr_bits + WB_DW : integer := 64; -- wishbone_data_bits + OIB_DW : integer := 8; + OIB_RATIO : integer := 0; -- encode + --WB_MAX_WR : integer := 1; -- could allow posted writes (no wait for ack) +-- BAR_BITS : integer := 16; -- in mc_pkg + BAR_INIT : std_ulogic_vector(BAR_BITS-1 downto 0) := x"FFFF" -- FFFFxxxx is local + ); + port( + clk : in std_ulogic; + rst : in std_ulogic; + + wb_cyc : in std_ulogic; + wb_stb : in std_ulogic; + wb_we : in std_ulogic; + wb_addr : in std_ulogic_vector(WB_AW-1 downto 0); + wb_wr_data : in std_ulogic_vector(WB_DW-1 downto 0); + wb_sel : in std_ulogic_vector((WB_DW/8)-1 downto 0); + wb_ack : out std_ulogic; + wb_err : out std_ulogic; + wb_stall : out std_ulogic; + wb_rd_data : out std_ulogic_vector(WB_DW-1 downto 0); + + oib_clk : out std_ulogic; + ob_data : out std_ulogic_vector(OIB_DW-1 downto 0); + ob_pty : out std_ulogic; + + ib_data : in std_ulogic_vector(OIB_DW-1 downto 0); + ib_pty : in std_ulogic; + + err : out std_ulogic; + int : out std_ulogic + ); +end mc; + + +architecture mc of mc is + +-- ff +signal config_d, config_q, config_rst: T_Config; +signal config_data : std_ulogic_vector(WB_DW-1 downto 0); + +signal wbseq_d, wbseq_q : std_ulogic_vector(3 downto 0); +signal wb_in_d, wb_in_q : wishbone_master_out; +signal wb_out_d, wb_out_q : wishbone_slave_out; + +signal oclk_d, oclk_q : std_ulogic; +signal oclk_last_d, oclk_last_q : std_ulogic; +signal odata_d, odata_q : std_ulogic_vector(OIB_DW-1 downto 0); +signal opty_d, opty_q : std_ulogic; +signal oseq_d, oseq_q : std_ulogic_vector(3 downto 0); +signal oclk_cnt_d, oclk_cnt_q : std_ulogic_vector(15 downto 0); +signal odata_cnt_d, odata_cnt_q : std_ulogic_vector(2 downto 0); + +signal idata_d, idata_q : std_ulogic_vector(OIB_DW-1 downto 0); +signal ipty_d, ipty_q : std_ulogic; +signal iseq_d, iseq_q : std_ulogic_vector(3 downto 0); +signal icapture_d, icapture_q : std_ulogic; +signal idata_cnt_d, idata_cnt_q : std_ulogic_vector(2 downto 0); + +-- misc +signal wbseq_err : std_ulogic; +signal wb_req, wb_req_err, wb_local, wb_local_rd, wb_local_wr, wb_remote_rd, wb_remote_wr, wb_req_stall, wb_sync : std_ulogic; +signal rd_data_load : std_ulogic_vector(WB_DW-1 downto 0); +signal ob_busy, ob_stall : std_ulogic; +signal local_rd_data : std_ulogic_vector(WB_DW-1 downto 0); +signal ob_header : std_ulogic_vector(OIB_DW-1 downto 0); + +signal oclk_advance, ob_complete, oseq_err, oseq_hold, iseq_err, rd_err, wr_err : std_ulogic; +signal odata_clear, odata_advance, oaddr_last, odata_last, odata_ld_header, odata_ld_addr, odata_ld_sel, odata_ld_data : std_ulogic; +signal oaddr_mux : std_ulogic_vector(7 downto 0); +signal odata_mux : std_ulogic_vector(7 downto 0); +signal ib_complete : std_ulogic; +signal oclk_match : std_ulogic; +signal oclk_toggle : std_ulogic_vector(15 downto 0); +signal config_write : std_ulogic; +signal wb_rd_resp, idata_clear : std_ulogic; +signal link_req_o, link_rsp_o, link_req_i, link_rsp_i : std_ulogic; +signal rd8_rsp, wr8_rsp, cache_inv, sync_ack, int_req : std_ulogic; +signal bad_header, good_header, pty_err, ld_rd_data : std_ulogic; +signal iseq_idle, idle_header, rd_rsp_data_done, rd_rsp_complete, wr_rsp_complete, int_req_complete, save_header : std_ulogic; + +begin + +-- these could sample the input bus for several of the bits on reset, but you need to know how wide the bus is +-- maybe use another pin to determine if config_pins or hardcoded default are used +--config_pins <= + +config_rst <= (oib_en => '1', oib_width => bus_width_enc(OIB_DW), oib_ratio => bus_ratio_enc(OIB_RATIO), cpol => '0', cpha => '0', + ib_en_pck => '1', rsvd0 => (others => '0'), int_req => '1', bar_en => '1', + bar => BAR_INIT, + rsvd1 => (others => '0'), + idle_flit => (others => '0'), rcv_header => (others => '0'), + err => (others => '0') + ); + +config_data <= config_q.oib_en & config_q.oib_width & config_q.oib_ratio & -- 63:56 + config_q.cpol & config_q.cpha & config_q.ib_en_pck & config_q.rsvd0 & config_q.int_req & config_q.bar_en & -- 55:48 + config_q.bar & -- 47:32 + config_q.rsvd1 & -- 31:24 + config_q.idle_flit & config_q.rcv_header & -- 23:08 + config_q.err; -- 07:00 + +int <= config_q.int_req; +--err <= or_reduce(config_q.err); +err <= config_q.err(7) or config_q.err(6) or config_q.err(5) or config_q.err(4) or config_q.err(3) or config_q.err(2) or config_q.err(1) or config_q.err(0); + +-- normal FF +FF: process(clk) begin + +if rising_edge(clk) then + + if rst = '1' then + + config_q <= config_rst; + wb_in_q <= wishbone_master_out_init; + wb_out_q <= wishbone_slave_out_init; + oclk_q <= '0'; + oclk_last_q <= '0'; + odata_q <= (others => '0'); + opty_q <= '1'; + wbseq_q <= (others => '1'); + oseq_q <= (others => '1'); + iseq_q <= (others => '1'); + oclk_cnt_q <= (others => '0'); + odata_cnt_q <= (others => '0'); + idata_cnt_q <= (others => '0'); + icapture_q <= '0'; + idata_q <= (others => '0'); + ipty_q <= '1'; + + else + + config_q <= config_d; + wb_in_q <= wb_in_d; + wb_out_q <= wb_out_d; + oclk_q <= oclk_d; + oclk_last_q <= oclk_last_d; + odata_q <= odata_d; + opty_q <= opty_d; + wbseq_q <= wbseq_d; + oseq_q <= oseq_d; + iseq_q <= iseq_d; + oclk_cnt_q <= oclk_cnt_d; + odata_cnt_q <= odata_cnt_d; + idata_cnt_q <= idata_cnt_d; + icapture_q <= icapture_d; + idata_q <= idata_d; + ipty_q <= ipty_d; + + end if; + +end if; + +end process FF; + +-- do something + +-- latch master - cyc/stb should be a single valid + +wb_req <= wb_cyc and wb_stb and not wb_out_q.stall; +wb_in_d.cyc <= '1' when wb_req = '1' else (wb_in_q.cyc and not wb_out_q.ack); +wb_in_d.stb <= '1' when wb_req = '1' else (wb_in_q.stb and not wb_out_q.ack); +wb_in_d.we <= wb_we when wb_req = '1' else wb_in_q.we; +wb_in_d.adr <= wb_addr when wb_req = '1' else wb_in_q.adr; +wb_in_d.dat <= wb_wr_data when wb_req = '1' else wb_in_q.dat; +wb_in_d.sel <= wb_sel when wb_req = '1' else wb_in_q.sel; + +-- process req + +-- move to unlatched +--wb_local <= config_q.bar_en and eq(wb_in_q.adr(WB_AW-1 downto WB_AW-BAR_BITS), config_q.bar); +wb_local <= config_q.bar_en and eq(wb_addr(WB_AW-1 downto WB_AW-BAR_BITS), config_q.bar); + +-- should be able to ack immediately rather than send latched (skip ack cycle in seq, send _d) + +--tbl WBSlaveSeq +--n wbseq_q wbseq_d +--n | wb_req | +--n | | | wb_local_rd +--n | | wb_we | |wb_local_wr +--n | | | | ||wb_remote_rd +--n | | | | |||wb_remote_wr +--n | | | | |||| wb_out_d.stall +--n | | | wb_local | |||| |wb_out_d.ack +--n | | | | ob_complete | |||| || oseq_hold +--n | | | | |rd_rsp_complete | |||| || | +--n | | | | ||wr_rsp_complete | |||| || | +--n | | | | ||| | |||| || | wbseq_err +--b 3210 | | | ||| 3210 |||| || | | +--t iiii i i i iii oooo oooo oo o o +--*-------------------------------------------------------------------------------------------------------------------- +--*-- Idle ------------------------------------------------------------------------------------------------------------ +--s 1111 0 - - --- 1111 0000 00 0 0 * zzz..zzz.... +--s 1111 1 0 1 --- 0001 1000 10 0 0 * read local +--s 1111 1 1 1 --- 0010 0100 10 0 0 * write local +--s 1111 1 0 0 --- 0100 0010 10 0 0 * read remote +--s 1111 1 1 0 --- 1000 0001 10 0 0 * write remote +--*-- Read Local ------------------------------------------------------------------------------------------------------ +--s 0001 - - - --- 1110 0000 11 0 0 * read ack +--*-- Write Local ----------------------------------------------------------------------------------------------------- +--s 0010 - - - --- 1110 0000 11 0 0 * write ack +--*-- Read Remote ----------------------------------------------------------------------------------------------------- +--s 0100 - - - --- ---- 0010 10 0 0 * +--s 0100 - - - 0-- 0100 ---- -- - - * read send +--s 0100 - - - 1-- 0101 ---- -- - - * read sent +--*-- Read Remote Wait ------------------------------------------------------------------------------------------------ +--s 0101 - - - --- ---- 0010 10 1 0 * +--s 0101 - - - -0- 0101 ---- -- - - * wait for response +--s 0101 - - - -1- 0110 ---- -- - - * response received +--*-- Read Remote Done------------------------------------------------------------------------------------------------- +--s 0110 - - - -0- 1110 0010 11 1 0 * read ack +--*-- Write Remote ---------------------------------------------------------------------------------------------------- +--s 1000 - - - --- ---- 0001 10 0 0 * +--s 1000 - - - 0-- 1000 ---- -- - - * write send +--s 1000 - - - 1-- 1001 ---- -- - - * write sent +--*-- Write Remote Wait ----------------------------------------------------------------------------------------------- +--s 1001 - - - --- ---- 0001 10 1 0 * +--s 1001 - - - --0 1001 ---- -- - - * wait for response +--s 1001 - - - --1 1010 ---- -- - - * response received +--*-- Write Remote Done ----------------------------------------------------------------------------------------------- +--s 1010 - - - --- 1110 0000 11 1 0 * write ack +--*-- Ack Cycle ------------------------------------------------------------------------------------------------------- +--s 1110 - - - --- 1111 0000 00 1 0 * last cycle of stall; ack=1 +--*-- ERROR ----------------------------------------------------------------------------------------------------------- +--s 0000 - - - --- 0000 0000 00 0 1 +--s 0011 - - - --- 0011 0000 00 0 1 +--s 0111 - - - --- 0111 0000 00 0 1 +--s 1011 - - - --- 1011 0000 00 0 1 +--s 1100 - - - --- 1100 0000 00 0 1 +--s 1101 - - - --- 1101 0000 00 0 1 +--*-------------------------------------------------------------------------------------------------------------------- + +--tbl WBSlaveSeq + +-- local + +-- move to unlatched +--config_write <= wb_local_wr and eq(wb_in_q.adr(31-BAR_BITS downto 0), 0); +config_write <= wb_local_wr and eq(wb_addr(31-BAR_BITS downto 0), 0); + +config_d.oib_en <= wb_in_d.dat(63) when config_write = '1' else config_q.oib_en; +config_d.oib_ratio <= wb_in_d.dat(62 downto 59) when config_write = '1' else config_q.oib_ratio; +config_d.oib_width <= wb_in_d.dat(58 downto 56) when config_write = '1' else config_q.oib_width; +config_d.cpol <= wb_in_d.dat(55) when config_write = '1' else config_q.cpol; +config_d.cpha <= wb_in_d.dat(54) when config_write = '1' else config_q.cpha; +config_d.ib_en_pck <= wb_in_d.dat(50) when config_write = '1' else config_q.ib_en_pck; +config_d.rsvd0 <= wb_in_d.dat(53 downto 51) when config_write = '1' else config_q.rsvd0; +config_d.int_req <= wb_in_d.dat(49) when config_write = '1' else (config_q.int_req or int_req_complete); +config_d.bar_en <= wb_in_d.dat(48) when config_write = '1' else config_q.bar_en; +config_d.bar <= wb_in_d.dat(47 downto 32) when config_write = '1' else config_q.bar; +config_d.rsvd1 <= wb_in_d.dat(31 downto 24) when config_write = '1' else config_q.rsvd1; +config_d.idle_flit <= wb_in_d.dat(23 downto 16) when config_write = '1' else config_q.idle_flit; +-- or write once until cleared? +config_d.rcv_header <= wb_in_d.dat(15 downto 8) when config_write = '1' else + gate_and(save_header, idata_q) or gate_and(not save_header, config_q.rcv_header); + +config_d.err <= wb_in_d.dat(7 downto 0) when config_write = '1' else + (config_q.err(7) or wbseq_err) & (config_q.err(6) or oseq_err) & (config_q.err(5) or iseq_err) & (config_q.err(4) or rd_err) & + (config_q.err(3) or wr_err) & (config_q.err(2) or pty_err) & (config_q.err(1) or bad_header) & config_q.err(0); + +-- outputs +wb_stall <= wb_out_q.stall; +wb_ack <= wb_out_q.ack; +wb_rd_data <= wb_out_q.dat; +wb_err <= '0'; + +-- send + +wb_sync <= '0'; +link_req_o <= '0'; +link_rsp_o <= '0'; + +--tbl HeaderEncode +--n wb_remote_rd ob_header +--n |wb_remote_wr | +--n ||wb_sync | +--n ||| link_req_o | +--n ||| |link_rsp_o | +--n ||| || | +--n ||| || | +--b ||| || 76543210 +--t iii ii oooooooo +--*------------------------------------------------- +--s 1-- -- 00000010 * read 8B +--s -1- -- 00000011 * write 8B +--s --1 -- 01000000 * sync and code +--s --- 1- 11110000 * link req and code +--s --- -1 11111000 * link rsp and code +--*------------------------------------------------- + +--tbl HeaderEncode + +-- bus clock + +with config_q.oib_ratio select + oclk_toggle <= x"0000" when "0000", -- toggle every clk 2:1 * fails right now * + x"0001" when "0001", -- toggle every 2 4:1 + x"0002" when "0010", -- toggle every 3 6:1 + x"0004" when "0011", -- toggle every 5 10:1 + x"0008" when "0100", -- toggle every 9 18:1 + x"0010" when "0101", -- toggle every 17 34:1 + x"0020" when "0110", -- toggle every 33 66:1 + x"0040" when "0111", -- toggle every 65 130:1 + x"0080" when "1000", -- toggle every 129 258:1 + x"0100" when "1001", -- toggle every 257 514:1 + x"0200" when others; -- toggle every 513 1026:1 + +oclk_match <= eq(oclk_cnt_q, oclk_toggle); + +oclk_cnt_d <= gate_and(not config_q.oib_en or config_write, x"0000") or + gate_and(config_q.oib_en and not config_write and oclk_match, x"0000") or + gate_and(config_q.oib_en and not config_write and not oclk_match, inc(oclk_cnt_q)); + +oclk_advance <= oclk_match and oclk_q; + +oib_clk <= oclk_q; + +oclk_d <= (oclk_q xor oclk_match) and config_q.oib_en; +oclk_last_d <= oclk_q and config_q.oib_en; + +-- cpol not used; clock always running + +with config_q.cpha select + icapture_d <= not oclk_last_q and oclk_q and config_q.oib_en when '0', -- rising + oclk_last_q and not oclk_q and config_q.oib_en when others; -- falling + +-- output + +--tbl SendSeq +-- +--n oseq_q oseq_d +--n | oseq_hold | +--n | |wb_remote_rd | odata_ld_header +--n | ||wb_remote_wr | |odata_ld_addr +--n | ||| | ||odata_ld_sel +--n | ||| oclk_advance | |||odata_clear +--n | ||| |oaddr_last | ||||odata_ld_data +--n | ||| ||odata_last | ||||| ob_complete +--n | ||| ||| | ||||| | +--n | ||| ||| | ||||| | oseq_err +--b 3210 ||| ||| 3210 ||||| | | +--t iiii iii iii oooo ooooo o o +--*------------------------------------------------------------------------------------------------------------------- +--*-- Idle ----------------------------------------------------------------------------------------------------------- +--s 1111 1-- --- 1111 00010 0 0 * zzz..zzz... +--s 1111 -00 --- 1111 00010 0 0 * zzz..zzz... +--s 1111 0-- 0-- 1111 00010 0 0 * ...slow... +--s 1111 01- 1-- 0001 10000 0 0 * start read +--s 1111 0-1 1-- 0001 10000 0 0 * start write +--*-- Remote Header -------------------------------------------------------------------------------------------------- +--s 0001 --- 0-- 0001 00000 0 0 * ...slow... +--s 0001 -1- 1-- 0010 01000 0 0 * begin address +--s 0001 --1 1-- 0010 01000 0 0 * begin address +--*-- Remote Address ------------------------------------------------------------------------------------------------- +--s 0010 --- 0-- 0010 01000 0 0 * ...slow... +--s 0010 --- 10- 0010 01000 0 0 * sending addr +--s 0010 --0 11- 1111 00010 1 0 * finish read request +--s 0010 --1 11- 0011 00110 0 0 * begin write sel +--*-- Remote Write (Sel) --------------------------------------------------------------------------------------------- +--s 0011 --- 0-- 0011 00000 0 0 * ...slow... +--s 0011 --- 1-- 0100 00001 0 0 * begin write data +--*-- Remote Write (Data) -------------------------------------------------------------------------------------------- +--s 0100 --- 0-- 0100 00001 0 0 * ...slow... +--s 0100 --- 1-0 0100 00001 0 0 * sending data +--s 0100 --- 1-1 1111 00001 1 0 * finish write request +--*-- ERROR ---------------------------------------------------------------------------------------------------------- +--s 0000 --- --- 0000 00000 0 1 +--s 0101 --- --- 0101 00000 0 1 +--s 0110 --- --- 0110 00000 0 1 +--s 0111 --- --- 0111 00000 0 1 +--s 1000 --- --- 1000 00000 0 1 +--s 1001 --- --- 1001 00000 0 1 +--s 1010 --- --- 1010 00000 0 1 +--s 1011 --- --- 1011 00000 0 1 +--s 1100 --- --- 1100 00000 0 1 +--s 1101 --- --- 1101 00000 0 1 +--s 1110 --- --- 1110 00000 0 1 +--*------------------------------------------------------------------------------------------------------------------- +--tbl SendSeq + + +-- 4 xfer for addr, 8 xfer for data +odata_cnt_d <= gate_and(odata_clear, "000") or + gate_and(odata_advance and odata_ld_addr, inc(odata_cnt_q)) or -- no clear? + gate_and(odata_advance and odata_ld_data, inc(odata_cnt_q)) or -- no clear? + gate_and(not odata_clear and not(odata_advance and (odata_ld_addr or odata_ld_data)), odata_cnt_q); + +oaddr_last <= eq(odata_cnt_q, 4); +odata_last <= eq(odata_cnt_q, 7); + +with odata_cnt_q select + oaddr_mux <= wb_in_q.adr(7 downto 0) when "000", + wb_in_q.adr(15 downto 8) when "001", + wb_in_q.adr(23 downto 16) when "010", + wb_in_q.adr(31 downto 24) when others; + +with odata_cnt_q select + odata_mux <= wb_in_q.dat(7 downto 0) when "000", + wb_in_q.dat(15 downto 8) when "001", + wb_in_q.dat(23 downto 16) when "010", + wb_in_q.dat(31 downto 24) when "011", + wb_in_q.dat(39 downto 32) when "100", + wb_in_q.dat(47 downto 40) when "101", + wb_in_q.dat(55 downto 48) when "110", + wb_in_q.dat(63 downto 56) when others; + +--wtf fix this to look normal +odata_d <= gate_and(odata_clear and odata_advance, config_q.idle_flit) or + gate_and(odata_ld_header, ob_header) or + gate_and(odata_ld_addr and odata_advance, oaddr_mux) or + gate_and(odata_ld_sel, wb_in_q.sel) or + gate_and(odata_ld_data and odata_advance, odata_mux) or + gate_and(not odata_ld_header and not odata_ld_sel and + not(odata_ld_addr and odata_advance) and + not odata_ld_sel and + not(odata_ld_data and odata_advance) and + not(odata_clear and odata_advance), odata_q); + +opty_d <= not(odata_d(7) xor odata_d(6) xor odata_d(5) xor odata_d(4) xor odata_d(3) xor odata_d(2) xor odata_d(1) xor odata_d(0)); + +odata_advance <= oclk_advance; -- oclk_match and not oclk_q and odata_ld_data; + +ob_data <= odata_q; +ob_pty <= opty_q; + +-- input + +with icapture_d select + idata_d <= ib_data when '1', + idata_q when others; + +with icapture_d select + ipty_d <= ib_pty when '1', + ipty_q when others; + + +--tbl HeaderDecode +--n idata_q wb_remote_rd rd8_rsp +--n | |wb_remote_wr |wr8_rsp +--n | || ||int_req +--n | || |||sync_ack +--n | || ||||cache_inv +--n | || |||||link_req_i +--n | || ||||||link_rsp_i +--n | || ||||||| +--n | || ||||||| good_header +--n | || ||||||| | +--b 76543210 || ||||||| | +--t iiiiiiii ii ooooooo o +--*------------------------------------------------- +--s 1000--10 1- 1000000 1 * read 8B resp and code +--s 1000--11 -1 0100000 1 * write 8B ack and code +--s 11000--- -- 0001000 1 * sync_ack and code (thread, type, etc.) +--s 11001--- -- 0000100 1 * cache inv +--s 11010--- -- 0010000 1 * int_req and code (ext, crit, stop, fry) +--s 11110--- -- 0000010 1 * link req and code +--s 11111--- -- 0000001 1 * link rsp and code +--*------------------------------------------------- +--tbl HeaderDecode + +idle_header <= eq(idata_q, config_q.idle_flit); +bad_header <= iseq_idle and icapture_q and not idle_header and not good_header; +pty_err <= icapture_q and not(idata_q(0) xor idata_q(1) xor idata_q(2) xor idata_q(3) xor idata_q(4) xor idata_q(5) xor idata_q(6) xor idata_q(7) xor ipty_q); + + +--tbl RecvSeq +-- +--n iseq_q iseq_d +--n | icapture_q | +--n | |idle_header | ld_rd_data +--n | ||rd8_rsp | |rd_rsp_complete +--n | |||wr8_rsp | ||wr_rsp_complete +--n | ||||int_req | |||int_req_complete +--n | |||||sync_ack | |||| +--n | ||||||cache_inv | |||| +--n | |||||||link_req_i | |||| +--n | ||||||||link_rsp_i | |||| idata_clear +--n | ||||||||| bad_header | |||| |save_header +--n | ||||||||| | | |||| || +--n | ||||||||| | rd_rsp_data_done | |||| || iseq_idle +--n | ||||||||| | | | |||| || |iseq_err +--b 3210 ||||||||| | | 3210 |||| || || +--t iiii iiiiiiiii i i oooo oooo oo oo +--*------------------------------------------------------------------------------------------------------------------- +--*-- Idle ----------------------------------------------------------------------------------------------------------- +--s 1111 --------- - - ---- ---- -- 10 +--s 1111 0-------- - - 1111 0000 10 -- * zzz..zzz... +--s 1111 11------- - - 1111 0000 10 -- * idle +--s 1111 1-------- 1 - 0110 0000 00 -- * bad header +--s 1111 1-1------ - - 1000 0000 00 -- * rd8 response +--s 1111 1--1----- - - 0001 0000 00 -- * wr8 ack +--s 1111 1---1---- - - 0010 0000 00 -- * int req +--s 1111 1----1--- - - 0110 0000 00 -- * other response +--s 1111 1-----1-- - - 0110 0000 00 -- * other response +--s 1111 1------1- - - 0110 0000 00 -- * other response +--s 1111 1-------1 - - 0110 0000 00 -- * other response +--*-- Rd Resp -------------------------------------------------------------------------------------------------------- +--s 1000 0 ------- - - 1000 0000 00 00 * ...slow... +--s 1000 1 ------- - 0 1000 1000 00 00 * Dx +--s 1000 1 ------- - 1 1111 1100 00 00 * Dlast +--*-- Wr Ack --------------------------------------------------------------------------------------------------------- +--s 0001 - ------- - - 1111 0010 00 00 * ack + code +--*-- Int Req -------------------------------------------------------------------------------------------------------- +--s 0010 - ------- - - 1111 0001 01 00 * int + code +--*-- Unknown Header ------------------------------------------------------------------------------------------------- +--s 0110 - ------- - - 0111 0000 01 00 * save header and wait for idle bus +--*-- Wait for Idle -------------------------------------------------------------------------------------------------- +--s 0111 0 ------- - - 0110 0000 00 00 * ...slow... +--s 0111 11------- - - 1111 0000 00 00 * idle +--s 0111 10------- - - 0110 0000 00 00 * non-idle +--*-- ERROR ---------------------------------------------------------------------------------------------------------- +--s 0000 --------- - - 0000 0000 00 01 +--s 0011 --------- - - 0011 0000 00 01 +--s 0100 --------- - - 0100 0000 00 01 +--s 0101 --------- - - 0101 0000 00 01 +--s 1001 --------- - - 1001 0000 00 01 +--s 1010 --------- - - 1010 0000 00 01 +--s 1011 --------- - - 1011 0000 00 01 +--s 1100 --------- - - 1100 0000 00 01 +--s 1101 --------- - - 1101 0000 00 01 +--s 1110 --------- - - 1110 0000 00 01 +--*------------------------------------------------------------------------------------------------------------------- +--tbl RecvSeq + + +-- read data +-- load immediately with local data +-- load 0:n for ib data +idata_cnt_d <= gate_and(icapture_q and ld_rd_data, inc(idata_cnt_q)) or + gate_and(not idata_clear and not(icapture_q and ld_rd_data), idata_cnt_q); + +rd_rsp_data_done <= eq(idata_cnt_q, 7); + +with wb_in_q.adr(7 downto 4) select + local_rd_data <= config_data when "0000", + (others => '1') when others; + +with idata_cnt_q select + rd_data_load <= wb_out_q.dat(63 downto 8) & idata_q when "000", + wb_out_q.dat(63 downto 16) & idata_q & wb_out_q.dat(7 downto 0) when "001", + wb_out_q.dat(63 downto 24) & idata_q & wb_out_q.dat(15 downto 0) when "010", + wb_out_q.dat(63 downto 32) & idata_q & wb_out_q.dat(23 downto 0) when "011", + wb_out_q.dat(63 downto 40) & idata_q & wb_out_q.dat(31 downto 0) when "100", + wb_out_q.dat(63 downto 48) & idata_q & wb_out_q.dat(39 downto 0) when "101", + wb_out_q.dat(63 downto 56) & idata_q & wb_out_q.dat(47 downto 0) when "110", + idata_q & wb_out_q.dat(55 downto 0) when others; + +wb_out_d.dat <= gate_and(wb_local_rd, local_rd_data) or + gate_and(wb_remote_rd and ld_rd_data, rd_data_load) or + gate_and(not wb_local_rd and not (wb_remote_rd and ld_rd_data), wb_out_q.dat); + +rd_err <= rd8_rsp and iseq_idle and icapture_q and not(eq(idata_q(4 downto 3), 0)); +wr_err <= wr8_rsp and iseq_idle and icapture_q and not(eq(idata_q(4 downto 3), 0)); + +---------------- Generated -------------------------- + +--vtable HeaderEncode +ob_header(7) <= + (link_req_o) or + (link_rsp_o); +ob_header(6) <= + (wb_sync) or + (link_req_o) or + (link_rsp_o); +ob_header(5) <= + (link_req_o) or + (link_rsp_o); +ob_header(4) <= + (link_req_o) or + (link_rsp_o); +ob_header(3) <= + (link_rsp_o); +ob_header(2) <= '0'; +ob_header(1) <= + (wb_remote_rd) or + (wb_remote_wr); +ob_header(0) <= + (wb_remote_wr); +--vtable HeaderEncode + +--vtable HeaderDecode +rd8_rsp <= + (idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and not idata_q(0) and wb_remote_rd); +wr8_rsp <= + (idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and idata_q(0) and wb_remote_wr); +int_req <= + (idata_q(7) and idata_q(6) and not idata_q(5) and idata_q(4) and not idata_q(3)); +sync_ack <= + (idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and not idata_q(3)); +cache_inv <= + (idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(3)); +link_req_i <= + (idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and not idata_q(3)); +link_rsp_i <= + (idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and idata_q(3)); +good_header <= + (idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and not idata_q(0) and wb_remote_rd) or + (idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and idata_q(0) and wb_remote_wr) or + (idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and not idata_q(3)) or + (idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(3)) or + (idata_q(7) and idata_q(6) and not idata_q(5) and idata_q(4) and not idata_q(3)) or + (idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and not idata_q(3)) or + (idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and idata_q(3)); +--vtable HeaderDecode + +--vtable WBSlaveSeq +wbseq_d(3) <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and not wb_local) or + (not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and not ob_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not wr_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and wr_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)); +wbseq_d(2) <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and not wb_local) or + (not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and not ob_complete) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not rd_rsp_complete) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and rd_rsp_complete) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)); +wbseq_d(1) <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and wb_local) or + (not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and rd_rsp_complete) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and wr_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)); +wbseq_d(0) <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and wb_local) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not rd_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not wr_rsp_complete) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)); +wb_local_rd <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and wb_local); +wb_local_wr <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and wb_local); +wb_remote_rd <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and not wb_local) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete); +wb_remote_wr <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and not wb_local) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)); +wb_out_d.stall <= + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and wb_local) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and wb_local) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and not wb_local) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and not wb_local) or + (not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)); +wb_out_d.ack <= + (not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)); +oseq_hold <= + (not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or + (wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)); +wbseq_err <= + (not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or + (wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)); +--vtable WBSlaveSeq + +--vtable SendSeq +oseq_d(3) <= + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or + (oseq_q(3) and not oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)); +oseq_d(2) <= + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and oclk_advance) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and not oclk_advance) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and not odata_last) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (not oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)) or + (not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)); +oseq_d(1) <= + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_rd and oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_wr and oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and oclk_advance and not oaddr_last) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and not oclk_advance) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or + (not oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)) or + (not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)); +oseq_d(0) <= + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_rd and oclk_advance) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_wr and oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and not oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and not oclk_advance) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)); +odata_ld_header <= + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_rd and oclk_advance) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_wr and oclk_advance); +odata_ld_addr <= + (not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_rd and oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_wr and oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and oclk_advance and not oaddr_last); +odata_ld_sel <= + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last); +odata_clear <= + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last); +odata_ld_data <= + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and oclk_advance) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and not oclk_advance) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and not odata_last) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last); +ob_complete <= + (not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last); +oseq_err <= + (not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or + (not oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (not oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)) or + (not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or + (oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)); +--vtable SendSeq + +--vtable RecvSeq +iseq_d(3) <= + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and rd8_rsp) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and not icapture_q) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and not rd_rsp_data_done) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or + (not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)); +iseq_d(2) <= + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and bad_header) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and sync_ack) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and cache_inv) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_req_i) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_rsp_i) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or + (not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and not idle_header) or + (not iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)); +iseq_d(1) <= + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and bad_header) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and int_req) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and sync_ack) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and cache_inv) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_req_i) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_rsp_i) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or + (not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and not idle_header) or + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)); +iseq_d(0) <= + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and wr8_rsp) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or + (not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)); +ld_rd_data <= + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and not rd_rsp_data_done) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done); +rd_rsp_complete <= + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done); +wr_rsp_complete <= + (not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)); +int_req_complete <= + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)); +idata_clear <= + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header); +save_header <= + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)); +iseq_idle <= + (iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0)); +iseq_err <= + (not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or + (not iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or + (iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or + (iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)); +--vtable RecvSeq + +end architecture mc; diff --git a/mc_pkg.vhdl b/mc_pkg.vhdl new file mode 100644 index 0000000..e777f83 --- /dev/null +++ b/mc_pkg.vhdl @@ -0,0 +1,186 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package mc_pkg is + +constant BAR_BITS : integer := 16; + +--types +type T_Config is record + oib_en : std_ulogic; + oib_ratio : std_ulogic_vector(3 downto 0); + oib_width : std_ulogic_vector(2 downto 0); + cpol : std_ulogic; + cpha : std_ulogic; + ib_en_pck : std_ulogic; + rsvd0 : std_ulogic_vector(2 downto 0); + bar_en : std_ulogic; + int_req : std_ulogic; + bar : std_ulogic_vector(BAR_BITS-1 downto 0); + --bar mask + rsvd1 : std_ulogic_vector(7 downto 0); + idle_flit : std_ulogic_vector(7 downto 0); + rcv_header : std_ulogic_vector(7 downto 0); + err : std_ulogic_vector(7 downto 0); +end record; + +-- functions +function inc(a: in std_ulogic_vector) return std_ulogic_vector; +function inc(a: in std_ulogic_vector; b: in integer) return std_ulogic_vector;use ieee.numeric_std.all; +function dec(a: in std_ulogic_vector) return std_ulogic_vector; +function eq(a: in std_ulogic_vector; b: in integer) return boolean; +function eq(a: in std_ulogic_vector; b: in integer) return std_ulogic; +function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return boolean; +function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return std_ulogic; + +function gate_and(a: in std_ulogic; b: in std_ulogic_vector) return std_ulogic_vector; +function or_reduce(slv: in std_ulogic_vector) return std_ulogic; +function and_reduce(slv: in std_ulogic_vector) return std_ulogic; + +function clog2(n : in integer) return integer; + +function bus_ratio_enc(n : in integer) return std_ulogic_vector; +function bus_width_enc(n : in integer) return std_ulogic_vector; + +end package mc_pkg; + + +package body mc_pkg is + +function inc(a: in std_ulogic_vector) return std_ulogic_vector is + variable res: std_ulogic_vector(0 to a'length-1); +begin + res := std_ulogic_vector(unsigned(a) + 1); + return res; +end function; + +function inc(a: in std_ulogic_vector; b: in integer) return std_ulogic_vector is + variable res: std_ulogic_vector(0 to a'length-1); +begin + res := std_ulogic_vector(unsigned(a) + b); + return res; +end function; + +function dec(a: in std_ulogic_vector) return std_ulogic_vector is + variable res: std_ulogic_vector(0 to a'length-1); +begin + res := std_ulogic_vector(unsigned(a) - 1); + return res; +end function; + +function eq(a: in std_ulogic_vector; b: in integer) return boolean is + variable res: boolean; +begin + res := unsigned(a) = b; + return res; +end function; + +function eq(a: in std_ulogic_vector; b: in integer) return std_ulogic is + variable res: std_ulogic; +begin + if unsigned(a) = b then + res := '1'; + else + res := '0'; + end if; + return res; +end function; + +function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return boolean is + variable res: boolean; +begin + res := unsigned(a) = unsigned(b); + return res; +end function; + +function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return std_ulogic is + variable res: std_ulogic; +begin + if unsigned(a) = unsigned(b) then + res := '1'; + else + res := '0'; + end if; + return res; +end function; + +function gate_and(a: in std_ulogic; b: in std_ulogic_vector) return std_ulogic_vector is + variable res: std_ulogic_vector(0 to b'length-1); +begin + if a = '1' then + res := b; + else + res := (others => '0'); + end if; + return res; +end function; + +function or_reduce(slv: in std_ulogic_vector) return std_ulogic is + variable res: std_logic := '0'; +begin + for i in 0 to slv'length-1 loop + res := res or slv(i); + end loop; + return res; +end function; + +function and_reduce(slv: in std_ulogic_vector) return std_ulogic is + variable res: std_logic := '1'; +begin + for i in 0 to slv'length-1 loop + res := res and slv(i); + end loop; + return res; +end function; + +function clog2(n : in integer) return integer is + variable i : integer; + variable j : integer := n - 1; + variable res : integer := 1; +begin + for i in 0 to 31 loop + if (j > 1) then + j := j / 2; + res := res + 1; + else + exit; + end if; + end loop; + return res; +end; + +function bus_ratio_enc(n : in integer) return std_ulogic_vector is + variable res : std_ulogic_vector(3 downto 0); +begin + case n is + when 1 => res := "0000"; + when 2 => res := "0001"; + when 4 => res := "0010"; + when 8 => res := "0011"; + when 16 => res := "0100"; + when 32 => res := "0101"; + when 64 => res := "0110"; + when 128 => res := "0111"; + when 256 => res := "1000"; + when 512 => res := "1001"; + when others => res := "1111"; + end case; + return res; +end; + +function bus_width_enc(n : in integer) return std_ulogic_vector is + variable res : std_ulogic_vector(2 downto 0); +begin + case n is + when 1 => res := "000"; + when 2 => res := "001"; + when 4 => res := "010"; + when 8 => res := "011"; + when 16 => res := "100"; + when others => res := "111"; + end case; + return res; +end; + +end package body mc_pkg;