]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/commitdiff
Multiple changes in FPGA, include Tumbl coprocessor
authorMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 18 Sep 2013 14:18:44 +0000 (16:18 +0200)
committerMartin Meloun <meloumar@cmp.felk.cvut.cz>
Wed, 18 Sep 2013 14:18:44 +0000 (16:18 +0200)
- remove deprecated control bram
- remove testing bcd counter
- fix IRC indexing reacting on index level
- update ucf file
- Tumbl: add sumbodule
- Tumbl: add lx-rocon implementation for Spartan6
- Tumbl: add primitive firmware (requires MicroBlaze binutils and gcc to compile)
- do not use coregen, infer the bram or use primitives
- Master CPU bus: now on 100 MHz instead of 72 MHz
- Master CPU bus: rd / bls is async and filtered

32 files changed:
.gitmodules
hw/Makefile
hw/bcd.vhd [deleted file]
hw/bus_bcd.vhd [deleted file]
hw/bus_calibration.vhd
hw/bus_control_bram.vhd [deleted file]
hw/bus_irc.vhd
hw/bus_tumbl.vhd [new file with mode: 0644]
hw/calibration_read_register.vhd
hw/calibration_write_register.vhd
hw/dff2.vhd [new file with mode: 0644]
hw/ipcore_dir/control_bram.ngc [deleted file]
hw/ipcore_dir/control_bram.vhd [deleted file]
hw/irc_reader.vhd
hw/irc_register.vhd
hw/lx-rocon.ucf
hw/lx-rocon_firmware/firmware.c [new file with mode: 0644]
hw/lx-rocon_firmware/start.S [new file with mode: 0644]
hw/lx-rocon_firmware/utils [new symlink]
hw/lx-rocon_tumbl/lx_rocon_dmem.vhd [new file with mode: 0644]
hw/lx-rocon_tumbl/lx_rocon_gprf_abd.vhd [new file with mode: 0644]
hw/lx-rocon_tumbl/lx_rocon_imem.vhd [new file with mode: 0644]
hw/lx-rocon_tumbl/lx_rocon_tumbl.vhd [new file with mode: 0644]
hw/lx-rocon_tumbl/tb/lx_rocon_tumbl_tb.vhd [new file with mode: 0644]
hw/lx_rocon_pkg.vhd [new file with mode: 0644]
hw/lx_rocon_top.prj
hw/lx_rocon_top.vhd
hw/qcounter.vhd
hw/tb/lx_rocon_top_tb.vhd
hw/tumbl [new symlink]
hw/xilinx_dualport_bram.vhd [new file with mode: 0644]
submodule/tumbl [new submodule]

index 6b3e7240aca59957e9934e64ff7e0144c8e456d9..58a36f47b51763bf313ac591cf38fe5bb20a6bfb 100644 (file)
@@ -16,3 +16,6 @@
 [submodule "submodule/ulan-drv"]
        path = submodule/ulan-drv
        url = git://git.code.sf.net/p/ulan/ulan-drv
+[submodule "submodule/tumbl"]
+       path = submodule/tumbl
+       url = ssh://git@rtime.felk.cvut.cz/fpga/lx-cpu1/tumbl.git
index 10aa237cfcb1bea1ae92fe88705234f25f9972c9..6d18021b17447cab4b77d551cda8969716cef2ba 100644 (file)
@@ -21,6 +21,7 @@
 #  - gen        : Transfer placed and routed NCD file into the bin file, which can
 #                 be then used to configure particular FPGA (this is further packaged
 #                 for SelectMap interface via the ARM CPU)
+#  - firmware   : Builds the firmware for Tumbl core
 
 # Dependicies are handled, so in most cases only 'download' target is called.
 
@@ -56,6 +57,26 @@ REQ_BIN            := $(REQB).bin
 REQ_PKG            := $(REQB).pkg
 REQ_SRC            := .
 
+REQ_FIRMWARE       := $(OUT)/imem.bin $(OUT)/imem.asm $(OUT)/dmem.bin $(OUT)/firmware.lst
+
+#===============================================================================
+
+MB_CROSS_COMPILE ?= mb-
+TARGET_CC := $(MB_CROSS_COMPILE)gcc
+TARGET_LD := $(MB_CROSS_COMPILE)ld
+TARGET_OBJCOPY := $(MB_CROSS_COMPILE)objcopy
+TARGET_OBJDUMP := $(MB_CROSS_COMPILE)objdump
+
+C_OBJS := $(OUT)/firmware.o
+A_OBJS :=
+CFLAGS := -mxl-soft-div -msoft-float -mno-xl-soft-mul -mxl-barrel-shift -Wno-main -Wl,-no-check-sections -fno-zero-initialized-in-bss -g -O2 -Wall
+AFLAGS := -D__ASSEMBLY__ $(CFLAGS)
+LDFLAGS := -static -nostdlib -defsym _STACK_SIZE=0x0200
+
+OBJS := $(OUT)/start.o $(C_OBJS) $(A_OBJS)
+
+FIRMWARE_DIR := ./lx-rocon_firmware
+
 #===============================================================================
 
 # Attempt to create a output directory.
@@ -68,7 +89,7 @@ $(if $(OUTPUT_DIR),,$(error output directory "$(OUT)" does not exist))
 #===============================================================================
 
 .PHONY: all
-all: pkg
+all: pkg firmware
 
 .PHONY: re-synthesize
 re-synthesize $(REQ_NGC): $(addprefix $(REQ_SRC)/,$(PRJ))
@@ -117,6 +138,29 @@ re-pkg $(REQ_PKG): $(OUT)/packager $(REQ_BIN)
        cd $(OUT); \
        ./packager le $(BIN) $(PKG)
 
+$(OUT)/%.o: $(FIRMWARE_DIR)/%.c
+       $(TARGET_CC) $(CFLAGS) -c $< -o $@
+
+$(OUT)/%.o: $(FIRMWARE_DIR)/%.S
+       $(TARGET_CC) $(AFLAGS) -c $< -o $@
+
+$(OUT)/firmware.elf: $(OBJS)
+       $(TARGET_LD) $(LDFLAGS) -T $(FIRMWARE_DIR)/utils/tumbl.ld-script -o $@ $(OBJS)
+
+$(OUT)/mb-dasm: $(FIRMWARE_DIR)/utils/mb-dasm.cpp
+       g++ $< -o $@
+       
+$(OUT)/bin2mem: $(FIRMWARE_DIR)/utils/bin2mem.c
+       gcc $< -o $@
+
+.PHONY: re-firmware
+re-firmware $(REQ_FIRMWARE): $(REQ_PKG) $(OUT)/mb-dasm $(OUT)/bin2mem $(OUT)/firmware.elf
+       $(TARGET_OBJCOPY) -O binary $(OUT)/firmware.elf -j .text -S $(OUT)/imem.bin
+       $(TARGET_OBJCOPY) -O binary $(OUT)/firmware.elf -j .data -S $(OUT)/dmem.bin
+       $(TARGET_OBJDUMP) -DSCz $(OUT)/firmware.elf > $@
+       cd $(OUT); \
+       ./mb-dasm imem.bin > imem.asm
+
 #===============================================================================
 
 .PHONY: clean
@@ -140,3 +184,6 @@ gen: $(REQ_BIN)
 
 .PHONY: pkg
 pkg: $(OUT)/packager $(REQ_PKG)
+
+.PHONY: firmware
+firmware: $(OUT)/mb-dasm $(OUT)/bin2mem $(REQ_FIRMWARE)
diff --git a/hw/bcd.vhd b/hw/bcd.vhd
deleted file mode 100644 (file)
index 611d897..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_arith.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-
--- Bcd for clock debugging purposes
-
-entity bcd is
-       generic
-       (
-               width : integer := 32
-       );
-       port
-       (
-               -- Reset
-               reset      : in std_logic;
-
-               -- Enabled
-               en         : in std_logic;
-
-               -- Clock
-               clk        : in std_logic;
-
-               -- Value
-               value      : out std_logic_vector((width-1) downto 0)
-       );
-end bcd;
-
-architecture Behavioral of bcd is
-       signal counter : std_logic_vector((width-1) downto 0);
-begin
-
-       value <= counter;
-
-       update: process (clk, reset)
-       begin
-
-               if reset = '1' then
-                       counter <= (others => '0');
-               elsif clk = '1' and clk'event then
-                       if en = '1' then
-                               counter <= counter + 1;
-                       end if;
-               end if;
-
-       end process;
-
-end Behavioral;
-
diff --git a/hw/bus_bcd.vhd b/hw/bus_bcd.vhd
deleted file mode 100644 (file)
index 76a847e..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.std_logic_arith.all;
-use ieee.std_logic_unsigned.all;
-use ieee.numeric_std.all;
-
--- BCD interconnection
-
-entity bus_bcd is
-       port
-       (
-               -- Reset
-               reset      : in std_logic;
-
-               -- Enable
-               en         : in std_logic;
-
-               -- Clock
-               clk        : in std_logic;
-
-               -- Chip enable
-               ce         : in std_logic;
-
-               -- Data bus (read only)
-               data_out   : out std_logic_vector(31 downto 0);
-
-               -- Bus signals
-               rd         : in std_logic;
-               ta         : out std_logic
-       );
-end bus_bcd;
-
-architecture Behavioral of bus_bcd is
-
-       signal value : std_logic_vector(31 downto 0);
-
-       component bcd
-       generic
-       (
-               width      : integer
-       );
-       port
-       (
-               reset      : in std_logic;
-               en         : in std_logic;
-               clk        : in std_logic;
-               value      : out std_logic_vector((width-1) downto 0)
-       );
-       end component;
-
-begin
-
-       my_bcd: bcd
-       generic map
-       (
-               width => 32
-       )
-       port map
-       (
-               reset => reset,
-               en => en,
-               clk => clk,
-               value => value
-       );
-
-       memory_bus: process(ce, rd, value)
-       begin
-
-               -- Init defaults
-               ta <= '1';
-               data_out <= (others => 'X');
-
-               if ce = '0' and rd = '0' then
-                       ta <= '0';
-                       -- ID in big endian
-                       data_out <= value;
-               end if;
-
-       end process;
-
-
-end Behavioral;
-
index 0d3c1682e4f07070e594cbee106616d9b782f8ba..a7bddf58a438fa1d0eeb44d677364d8afa237fd8 100644 (file)
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
 
 -- Memory bus calibration
 -- Holds the signal for one clock to simulate longest route
@@ -38,11 +39,9 @@ architecture Behavioral of bus_calibration is
        -- Wiring
        signal read1_out : std_logic_vector(31 downto 0);
        signal read1_ta : std_logic;
-       signal read1_ce : std_logic;
 
        signal read2_out : std_logic_vector(31 downto 0);
        signal read2_ta : std_logic;
-       signal read2_ce : std_logic;
 
        signal write1_out : std_logic_vector(31 downto 0);
        signal write1_ta : std_logic;
@@ -52,34 +51,6 @@ architecture Behavioral of bus_calibration is
        signal write2_ta : std_logic;
        signal write2_ce : std_logic;
 
-       component calibration_read_register
-       generic
-       (
-               id          : std_logic_vector(31 downto 0)
-       );
-       port
-       (
-               ce          : in std_logic;
-               data_out    : out std_logic_vector(31 downto 0);
-               rd          : in std_logic;
-               ta          : out std_logic
-       );
-       end component;
-
-       component calibration_write_register
-       port
-       (
-               clk         : in std_logic;
-               reset       : in std_logic;
-               ce          : in std_logic;
-               data_in     : in std_logic_vector(31 downto 0);
-               data_out    : out std_logic_vector(31 downto 0);
-               rd          : in std_logic;
-               bls         : in std_logic_vector(3 downto 0);
-               ta          : out std_logic
-       );
-       end component;
-
 begin
 
        -- First read calibration register (0xAAAAAAAA)
@@ -90,7 +61,6 @@ begin
        )
        port map
        (
-               ce => read1_ce,
                rd => rd,
                ta => read1_ta,
                data_out => read1_out
@@ -104,7 +74,6 @@ begin
        )
        port map
        (
-               ce => read2_ce,
                rd => rd,
                ta => read2_ta,
                data_out => read2_out
@@ -145,8 +114,6 @@ begin
                if clk = '1' and clk'event then
 
                        -- Defaults
-                       read1_ce <= '1';
-                       read2_ce <= '1';
                        write1_ce <= '1';
                        write2_ce <= '1';
 
@@ -158,11 +125,9 @@ begin
                        if ce = '0' then
                                case address is
                                        when "00" => -- Read1
-                                               read1_ce <= '0';
                                                ta <= read1_ta;
                                                data_out <= read1_out;
                                        when "01" => -- Read2
-                                               read2_ce <= '0';
                                                ta <= read2_ta;
                                                data_out <= read2_out;
                                        when "10" => -- Write1
diff --git a/hw/bus_control_bram.vhd b/hw/bus_control_bram.vhd
deleted file mode 100644 (file)
index 44e9aee..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-
--- Wrapper for the memory bus for CPU and the BRAM
-
-entity bus_control_bram is
-       port
-       (
-               -- Clock
-               clk : in std_logic;
-
-               -- This is wired to CPU memory bus
-    ena : in std_logic;
-    wea : in std_logic_vector(3 downto 0);
-    addra : in std_logic_vector(8 downto 0);
-    dina : in std_logic_vector(31 downto 0);
-    douta : out std_logic_vector(31 downto 0);
-               taa : out std_logic;
-
-               -- This is wired to control unit bus
-    enb : in std_logic;
-    web : in std_logic_vector(3 downto 0);
-    addrb : in std_logic_vector(8 downto 0);
-    dinb : in std_logic_vector(31 downto 0);
-    doutb : out std_logic_vector(31 downto 0)
-  );
-end bus_control_bram;
-
-architecture Behavioral of bus_control_bram is
-
-       signal neg_ena : std_logic;
-       signal neg_wea : std_logic_vector(3 downto 0);
-
-       component control_bram
-       port
-       (
-    clka : in std_logic;
-    ena : in std_logic;
-    wea : in std_logic_vector(3 downto 0);
-    addra : in std_logic_vector(8 downto 0);
-    dina : in std_logic_vector(31 downto 0);
-    douta : out std_logic_vector(31 downto 0);
-
-    clkb : in std_logic;
-    enb : in std_logic;
-    web : in std_logic_vector(3 downto 0);
-    addrb : in std_logic_vector(8 downto 0);
-    dinb : in std_logic_vector(31 downto 0);
-    doutb : out std_logic_vector(31 downto 0)
-  );
-       end component;
-
-begin
-
-       -- Wire it to the actual BRAM
-       my_bram: control_bram
-       port map
-       (
-               clka => clk,
-               ena => neg_ena,
-               wea => neg_wea,
-               addra => addra,
-               dina => dina,
-               douta => douta,
-
-               clkb => clk,
-               enb => enb,
-               web => web,
-               addrb => addrb,
-               dinb => dinb,
-               doutb => doutb
-       );
-
-       -- Transaction acknowledge
-       my_bram_ta: process(clk)
-       begin
-
-               -- It puts there data synchronously with clock, so make the same for ack
-               if clk = '1' and clk'event then
-                       taa <= ena;
-               end if;
-
-       end process;
-
-       -- Wire negated inputs
-       my_bream_neg: process(ena, wea)
-       begin
-
-               neg_ena <= not ena;
-               neg_wea <= not wea;
-
-       end process;
-
-end Behavioral;
-
index 722f6fafb3ba9f948c7d42b1603b13005f51bd41..8e93b3f63e8adf4f2242ff2a1d0790996c07b924 100644 (file)
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
 
 -- IRC bus interconnect: memory region for IRC
 
@@ -68,24 +69,6 @@ architecture Behavioral of bus_irc is
        signal irc4_ta : std_logic;
        signal irc4_ce : std_logic_vector(1 downto 0);
 
-       -- IRC register
-       component irc_register
-       port
-       (
-               clk      : in std_logic;
-               reset    : in std_logic;
-               a0, b0   : in std_logic;
-               index0   : in std_logic;
-               mark0    : in std_logic;
-               data_in  : in std_logic;
-               data_out : out std_logic_vector(31 downto 0);
-               ce       : in std_logic_vector(1 downto 0);
-               rd       : in std_logic;
-               ta       : out std_logic;
-               wr       : in std_logic
-       );
-       end component;
-
 begin
 
        -- IRC for first axis
@@ -199,8 +182,7 @@ begin
                                        data_out <= irc4_out;
                                        ta <= irc4_ta;
 
-                               when others =>
-                                       data_out <= (others => 'X');
+                               when others => NULL;
 
                        end case;
 
diff --git a/hw/bus_tumbl.vhd b/hw/bus_tumbl.vhd
new file mode 100644 (file)
index 0000000..0661347
--- /dev/null
@@ -0,0 +1,268 @@
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.mbl_Pkg.all;
+use work.lx_rocon_pkg.all;
+
+-- Connects tumbl to the Master CPU
+
+entity bus_tumbl is
+       port
+       (
+               -- Clock
+               clk_100m : in std_logic;
+               clk_50m  : in std_logic;
+
+               -- Chip enable
+               ce       : in std_logic;
+
+               -- Global Reset
+               reset    : in std_logic;
+
+               -- Master CPU bus for the memory
+    rd       : in std_logic;
+    bls      : in std_logic_vector(3 downto 0);
+    address  : in std_logic_vector(11 downto 0);
+    data_in  : in std_logic_vector(31 downto 0);
+    data_out : out std_logic_vector(31 downto 0);
+               ta       : out std_logic;
+
+               -- Tumbl extrenal memory bus
+               XMEMB_sel_o :  out std_logic;
+               XMEMB_i     :  in DMEMB2CORE_Type;
+               XMEMB_o     :  out CORE2DMEMB_Type
+  );
+end bus_tumbl;
+
+architecture Behavioral of bus_tumbl is
+
+       -- Internal state
+       signal tumbl_reset : std_logic;
+       signal tumbl_halt : std_logic;
+       signal tumbl_int : std_logic;
+       signal tumbl_trace : std_logic;
+       signal tumbl_trace_kick : std_logic; -- driven by 50M clock
+       signal tumbl_trace_kick_ack : std_logic; -- driven by 50M clock
+       signal tumbl_trace_kick_req : std_logic; -- driven by 100M clock
+       signal tumbl_done : std_logic; -- driven by 50M clock
+       signal tumbl_bad_op : std_logic; -- driven by 50M clock
+
+       -- Tumbl PC (copy it with cpu clock and then wire further)
+       signal tumbl_pc : std_logic_vector(31 downto 0); -- driven by 50M clock
+
+       -- Internal memory signals
+       signal imem_en : std_logic;
+       signal dmem_en : std_logic;
+
+       signal imem_we : std_logic_vector(3 downto 0);
+       signal dmem_we : std_logic_vector(3 downto 0);
+
+       signal imem_dout : std_logic_vector(31 downto 0);
+       signal dmem_dout : std_logic_vector(31 downto 0);
+
+       -- Internal bus structure
+       -- 12 address bits: 2 bits for selection, 10 bits for address
+       --
+       -- Selection:
+       -- 00 - imem
+       -- 01 - dmem
+       -- 10 - reserved
+       -- 11 - registers
+
+       -- Registers
+       -- 0x000
+       --
+       -- Bit 0: R/W - Reset
+       -- Bit 1: R/W - Interrupt
+       -- Bit 2: R/W - Halt
+       -- Bit 3: R/W - Trace
+       -- Bit 3: R - Done
+       -- Bit 4: R - Bad Op (halts the core until reset)
+
+       -- 0x001
+       -- Bit 0: W - Write 1 for trace kick, R - Read internal signals
+
+       -- 0x002
+       -- Tumbl program counter (R)
+
+begin
+
+       -- Wire it to the tumbl
+       I_TUMBL: lx_rocon_tumbl
+       generic map
+       (
+               IMEM_ABITS_g => 11,
+               DMEM_ABITS_g => 12,
+               --
+               USE_HW_MUL_g => true,
+               USE_BARREL_g => true
+       )
+       port map
+       (
+               clk_i => clk_50m,
+               rst_i => tumbl_reset,
+               halt_i => tumbl_halt,
+               int_i => tumbl_int,
+               trace_i => tumbl_trace,
+               trace_kick_i => tumbl_trace_kick,
+
+               pc_o => tumbl_pc,
+
+               -- Internal memory (instruction)
+               imem_clk => clk_100m,
+    imem_en => imem_en,
+    imem_we => imem_we,
+    imem_addr => address(8 downto 0),
+    imem_din => data_in,
+    imem_dout => imem_dout,
+
+               -- Internal memory (data)
+               dmem_clk => clk_100m,
+    dmem_en => dmem_en,
+    dmem_we => dmem_we,
+    dmem_addr => address(9 downto 0),
+    dmem_din => data_in,
+    dmem_dout => dmem_dout,
+
+               -- External memory bus
+               XMEMB_sel_o => XMEMB_sel_o,
+               XMEMB_i => XMEMB_i,
+               XMEMB_o => XMEMB_o,
+               --
+               done_o => tumbl_done,
+               bad_op_o => tumbl_bad_op
+       );
+
+       -- Wiring
+       wiring: process(ce, rd, bls, address, imem_en, imem_dout, dmem_en, dmem_dout,
+                       tumbl_reset, tumbl_int, tumbl_halt, tumbl_trace, tumbl_done, tumbl_bad_op, tumbl_pc)
+       begin
+
+               if ce = '0' and address(11 downto 10) = "00" then
+                       imem_en <= '1';
+               else
+                       imem_en <= '0';
+               end if;
+
+               if ce = '0' and address(11 downto 10) = "01" then
+                       dmem_en <= '1';
+               else
+                       dmem_en <= '0';
+               end if;
+
+               if imem_en = '1' and tumbl_reset = '1' then
+                       imem_we <= not bls;
+               else
+                       imem_we <= "0000";
+               end if;
+
+               if dmem_en = '1' and tumbl_reset = '1' then
+                       dmem_we <= not bls;
+               else
+                       dmem_we <= "0000";
+               end if;
+
+               if imem_en = '1' then
+                       data_out <= imem_dout;
+               elsif dmem_en = '1' then
+                       data_out <= dmem_dout;
+               elsif ce = '0' and rd = '0' and address(11 downto 10) = "11" then
+                       if address(9 downto 0) = "0000000000" then
+                               data_out(0) <= tumbl_reset;
+                               data_out(1) <= tumbl_int;
+                               data_out(2) <= tumbl_halt;
+                               data_out(3) <= tumbl_trace;
+                               data_out(4) <= tumbl_done;
+                               data_out(5) <= tumbl_bad_op;
+                               data_out(31 downto 5) <= (others => '0');
+                       elsif address(9 downto 0) = "0000000010" then
+                               data_out <= tumbl_pc;
+                       else
+                               data_out <= (others => 'X');
+                       end if;
+               else
+                       data_out <= (others => 'X');
+               end if;
+
+       end process;
+
+       -- Transaction acknowledge and writing to registers
+       -- The clock are synchronous!
+       update: process(clk_100m)
+       begin
+
+               -- Update on the 100 MHz clock
+               if clk_100m = '1' and clk_100m'event then
+                       ta <= '1';
+
+                       if imem_en = '1' or dmem_en = '1' then
+                               ta <= '0';
+                       end if;
+
+                       if reset = '1' then
+                               tumbl_reset <= '1';
+                               tumbl_int <= '0';
+                               tumbl_halt <= '0';
+                               tumbl_trace <= '0';
+                               tumbl_trace_kick_req <= '0';
+                       else
+
+                               if tumbl_trace_kick_ack = '1' then
+                                       tumbl_trace_kick_req <= '0';
+                               end if;
+
+                               if ce = '0' and address(11 downto 10) = "11" then
+                                       if bls(0) = '0' then
+                                               if address(9 downto 0) = "0000000000" then
+                                                       tumbl_reset <= data_in(0);
+                                                       tumbl_int <= data_in(1);
+                                                       tumbl_halt <= data_in(2);
+                                                       tumbl_trace <= data_in(3);
+                                               elsif address(9 downto 0) = "0000000001" then
+                                                       if data_in(0) = '1' and tumbl_trace_kick = '0' then
+                                                               tumbl_trace_kick_req <= '1';
+                                                       end if;
+                                               end if;
+                                       end if;
+
+                                       if rd = '0' then
+                                               ta <= '0';
+                                       end if;
+                               end if;
+                       end if;
+
+               end if;
+       end process;
+
+       -- Update tracing
+       tumbl: process(clk_50m)
+       begin
+
+               -- Update on the 50 MHz clock
+               if clk_50m = '1' and clk_50m'event then
+
+                       if reset = '1' then
+                               tumbl_trace_kick <= '0';
+                               tumbl_trace_kick_ack <= '0';
+                       else
+                               if tumbl_trace_kick = '0' and tumbl_trace_kick_req = '1' then
+                                       tumbl_trace_kick <= '1';
+                                       tumbl_trace_kick_ack <= '1';
+                               else
+                                       tumbl_trace_kick <= '0';
+                               end if;
+                       end if;
+
+                       if tumbl_trace_kick_req <= '0' then
+                               tumbl_trace_kick_ack <= '0';
+                       end if;
+
+               end if;
+
+       end process;
+
+end Behavioral;
+
index ebefc3902f02a3c09c830152ea20af73d4d2c0b7..86af59466a51feed3665d642e6fa2552c07d1b85 100644 (file)
@@ -14,9 +14,6 @@ entity calibration_read_register is
        );
        port
        (
-               -- Chip enable
-               ce          : in std_logic;
-
                -- Data bus (read only)
                data_out    : out std_logic_vector(31 downto 0);
 
@@ -29,17 +26,11 @@ end calibration_read_register;
 architecture Behavioral of calibration_read_register is
 begin
 
-       memory_bus: process(ce, rd)
+       memory_bus: process(rd)
        begin
 
-               -- Init defaults
-               ta <= '1';
-               data_out <= (others => 'X');
-
-               if ce = '0' and rd = '0' then
-                       ta <= '0';
-                       data_out <= id;
-               end if;
+               ta <= rd;
+               data_out <= id;
 
        end process;
 
index 546a33179886249b95f83b65089b95fcaf630742..4dd7330e397ea9202a112ee6bb6f68ae7addd914 100644 (file)
@@ -35,30 +35,24 @@ architecture Behavioral of calibration_write_register is
 begin
 
        -- Read is immideate
-       memory_bus_read: process(ce, rd, value)
+       memory_bus_read: process(rd, value)
        begin
 
-               -- Init defaults
-               ta <= '1';
-               data_out <= (others => 'X');
-
-               if ce = '0' and rd = '0' then
-                       ta <= '0';
-                       data_out <= value;
-               end if;
+               ta <= rd;
+               data_out <= value;
 
        end process;
 
        -- Write waits for clock
-       memory_bus_write: process(clk, reset)
+       memory_bus_write: process(clk)
        begin
 
-               if reset = '1' then
-                       value <= (others => '0');
-               end if;
-
                if clk = '1' and clk'event then
 
+                       if reset = '1' then
+                               value <= (others => '0');
+                       end if;
+
                        if ce = '0' then
 
                                if reset = '0' and bls /= "1111" then
diff --git a/hw/dff2.vhd b/hw/dff2.vhd
new file mode 100644 (file)
index 0000000..28d92b4
--- /dev/null
@@ -0,0 +1,41 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+
+-- D circuit (filtered)
+
+entity dff2 is
+  port
+       (
+    clk   : in std_logic;
+               reset : in std_logic;
+    d     : in std_logic;
+    q     : out std_logic
+  );
+end dff2;
+
+architecture behavioral of dff2 is
+       signal last_d : std_logic;
+  signal data: std_logic;
+begin
+  q <= data;
+
+  seq: process(clk)
+  begin
+    if clk = '1' and clk'event then
+                       if reset = '1' then
+                               last_d <= '0';
+                               data <= '0';
+                       else
+                               if d = last_d then
+                                       data <= d;
+                               end if;
+                       end if;
+
+                       last_d <= d;
+               end if;
+  end process;
+
+end behavioral;
diff --git a/hw/ipcore_dir/control_bram.ngc b/hw/ipcore_dir/control_bram.ngc
deleted file mode 100644 (file)
index 2dbab84..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-XILINX-XDB 0.1 STUB 0.1 ASCII
-XILINX-XDM V1.6e
-$0a6\7f44<,[o}e~g`n;"2*73>(-80!<;40123416<89:;<=>?0123456789:;<=>?0123456789:;<=>?0123456789:;<=>?012345679h1:?7GAPTV9EABUI^XJHI\31383:4g<9:0BB][[:@FGVGTCIMNY0<<50?37?40=AGZ^X7JFAEK?50<768>0=;4FNQWW>AOEL@6:97>114922?IR\Y__6IANDN>21?699<1::7AZTQWW>AIELF6:97>11591>LHW]]0OE]OKIQ>2>586<281EC^ZT;FJTGBNX5;1<3?<;38JJUSS2^OJ[HB31;2=56=52@D[YY4XECUFQ97=87;>7?4@UURVP?BHXHND\1?50?36?7<H]]Z^X7J@PCFLT97=87;87><5IORVP?bnfh68=7>112906?OIX\^1hd`m<2394;723:81CXZ_UU8gkprf4:;1<3?:;209KPRW]]0ocxzm<2394;773=0BB][[:vgb86<768:087GAPTV9s`d;;3:5h68|ly;wub73<$8:>675IORVP?gcl{k747>1139:>LHW]]0jhi|m<983:`=FLMXJ[_OKDS>3:c=FLMXJ[_OKDS>24;`<IMNYMZ\NDEP?548692KOH_OXR@FGV975294m7LJKR@UQEABU4885i6OKDSCTVDBCZ5;5i6OKDSCTVDBCZ585i6OKDSCTVDBCZ595i6OKDSCTVDBCZ5>5i6OKDSCTVDBCZ5?5i6OKDSCTVDBCZ5<5i6OKDSCTVDBCZ5=5i6OKDSCTVDBCZ525i6OKDSCTVDBCZ535i6OKDS@Q@DBCZ5:5j6OKDS@Q@DBCZ5;;2k5NDEPAVAGCL[6:=3?>;@FGVGTCIMNY0<<50?d8EABUJ[NJHI\313<f?DBCZKXOMIJ]<0<f?DBCZKXOMIJ]<3<f?DBCZKXOMIJ]<2<f?DBCZKXOMIJ]<5<f?DBCZKXOMIJ]<4<f?DBCZKXOMIJ]<7<f?DBCZKXOMIJ]<6<f?DBCZKXOMIJ]<9<f?DBCZKXOMIJ]<8<0?DJK02H^_RGAFN08G@753JBNOFQCIBGMW@YSQYO?7NBD079@HN7?8?1H@F<8049@HN4_02IGG?V>8178GIM>8<1H@FO>7:AOOD7C:>1H@FO>D558GIMF9M227NBDAVP@HN3<KEAI=45LLJ@Q@FJL=2IGGN?:;BNH@43<KEAOZn5LLJFU[AOQAMO>7NBDFY:8GIMAP82;56M@MLKWP@B6<2ID^HQHEOGQEQOHFVCEJB94CSGBP@Bd3MK_MRYFDUJ\Ef=CI]KT[DJ[H^@;?AOFL@6;245KI@FJ846912NBMIG310<:?AOFL@6:>374DHCGM974601OELJF<06=f>BNIMC7=84?>89GMDBN48?546JFAEK?5;><L@KOE1<18:FJEAO;;720HDOKI=6=<>BNIMC79364DHCGM90902NBMIG37?:8@LGCA52546JFAEK?=;><L@HOE1>19:FJFAO;99427IGMDH>25;?<L@HOE1?=>89GMGBN489556JFBEK?518e3MCIHD2>5;2==>BNJMC7=807;EKA@L:6611OEOJF<3<;?AOEL@68255KICFJ818?3MCIHD2:>99GMGBN4?437IGMDH>4:==CAKNB0507;EKA@L:>6h1OE]OKIQ>3:f=CAYKOE]2>:1<b?AOWIMC[0<0n;EKSFAOW494h7IG_BEKS84<76h1OE]LKIQ>2:==CGHND0=06;EMB@J:68730HBOKO=32:<=CGHND0<<19:FLEAI;9:427IANDN>20;d<LFKOC1?::1<:?AIFLF6:9364DNCGK97902NDMIA32?:8@JGCG59546J@AEM?0;><LFKOC1;18:FLEAI;>720HBOKO=5=<>BHIME74364DNCGK9?9?2NDMR\JG99GKGBH49427IAMDN>24;?<LFHOC1?>>89GKGBH488556J@BEM?568>3MEIHB2>4?`8@JDCG5;>6=06;EMA@J:6=720HBLKO=3=<>BHJME7>364DN@GK95902NDNIA34?:8@JDCG5?546J@BEM?2;><LFHOC1918:FLFAI;0720HBLKO=;=3>BHJVXNKl5KOQCGKU:76j1OC]OKOQ>2>58f3ME[MIA_<0<b?AIWJME[0=0l;EMSFAIW480;2l5KOQ@GKU:66>1NBLY]EO58AKDULLDi7H@PRRVQEHYFj2OES_][R@O\F0=AIEYN=6I<;FLG<>OIA]ZT<=64IOKWTZ6602CEEY^P03:8MKOSXV:8;6GAIU]342=NF@^T<<94IOKW[5403@DBXR><7:KMMQY7<>1BBDZP0458MKOSW9<<7D@FT^243>OIA]U;4:5FNHV\4<1<AGC_S=O8;HLJPZ6E?2CEEYQ?C69JJLRX8M=0ECG[_1G4?LHN\V:M;6GAIU]242=NF@^T=<94IOKW[4403@DBXR?<7:KMMQY6<>1BBDZP1458MKOSW8<<7D@FT^343>OIA]U:4:5FNHV\5<1<AGC_S<O8;HLJPZ7E?2CEEYQ>C69JJLRX9M=0ECG[_0G4?LHN\V;M:6GAIU]B2>OIA]UI56GAIU]EMIC13EEJHHJ9;MM@O@B03EELENOCc:ObnjtQm{ybccm4MhllvScu{`ee>6@>7:LFPRIUC=1ECCK>7:MSPLKNRLU[^DCFTHTFWZH@K>1[";6k_M68TDTSi2ZBBRLZSHF[f>VNFVH^_COBE79SWAIIM01YM@L7BVGQ<>TFEVGDHH84RDE@ADd<ZLMHIO\JGBG7?WUSI>1Y_YL]SU58VVRSQYOn7_][_QPJKWOSQVKn7_][_QPJKWOSQVH:=6]GRDE\A]RUIJ^TBJMj;RJQABYJAGUXEWK>3:QJIZEHDECXEB@PCIG@O3=TG\XHI:5\RWCO[D1<[[\J@RL9;RVBPPU33ZSEO>5[DQ68P\VB?91^<"v|t^`ooZkbeVmnbh|ntnp,ckgsa\7foiaj aaukuaZdkcVgnaRijn.tbhlb)kz~y#\7foblnms_5[)zhg%~"}9_hljp+tfe&^YYHQKP/RQMH?)zhg<<6[?/yqw[gjlWdofSjkaescwkw)`fh~bzhlbg/lbplpbWkf`S`kb_fgm+sgkam$h\7fy| r`ookjv\9T$ym` }/r4\mkos&{kf#Y\ZE^FS*UTNE0$ym`9?;T2,|vrXjeaTahcPgdlfvdrhz&memygyecod*kgsa\7foTnaePmdo\c`h(~hfbh#m|ts-qehjhgyQ9Q#|nm/p,w3Ynf`~%~lc TSWF[AV)X[CF5#|nm628Q5)\7f{}Ui`fQbel]dakcui}ey#j`nthtffha)fh~bzhQmlj]nahY`mg%}magk.bqwv*tfeeed|V=R.scn*w)t>Vceey }al-WVPCXLY$[^DC6.scng>STM[U]E^GMLD;8RLCPW]S[I45XE@UFH969j2]NMZKC<083:<=PMH]N@1?19:UFFRCR494i7ZKMWDW?5?6912]NNZKZ<0<a?RTN\LUME_][c:UQMQCXEFNNSLm4WSKWAZKHLLUI=i5WIMKM\(^CJ):%=-][UC"3*4&F[JCB:6V\TMKA3>^T\VMEHo5W_BMQAZOINF<0TilPIed8\anXX{cfZh||inl24>^ceVGjfb|Yesqjkk773QnfS@gaosTfvvohf:1S\7fy=4Ydq;?dbczh6;255ndepb848?3hno~l2=>99b`atf4:437ljkr`>7:==flmxj0807;`fgvd:1611jhi|n<6<b?dbczh636=07;`fgvd:?611jhi|m<1<;?dbczk6:255ndepa878?3hno~o2<>99b`ate4=437ljkrc>6:==flmxi0;07;`fgvg:06h1jhi|m<983:==flmxi050>8:`ooZkbeVmnbRijndpjgZet|{;37obd_lgn[bciWyxbaRyfduj\54><jeaTahcPgdl\twojW~coxeQ=199ahnYjmdUlicQ\7frho\slbs`V9:46lck^ofiZabfVzye`Qxievk[1453kf`S`kb_fgm[utneV}ym}~jr^q5[lhn|V;9>6lck^ofiZabfVzye`Qxr`rsawYt>VceeyQ=239ahnYjmdUlicQ\7frho\swgwxlxT\7f;Qfnhv\774<jeaTahcPgdl\twojW~xj|}k}_r4\mkosW=l0naePmdo\c`hX|fz:<6lck^ofiZabfV|<S><l;cnh[hcjWnoeS{9P3-"[mioip)ID^H.Heogqeqiu(8>%:<:4bmi\i`kXoldTz:Q<_yqw56=edbUfi`Qfnqww[gjhkb;?7obd_lgn[jssx|~Tnaalk59`hng33jf`nn5loovqkiYezhg?j85loovqkiYezhg'naePmdo\c`hX~>U8 vmPaefqeZqnl}b65!mPaefqfZqnl}b65!mPamelvlroe4:'oRowi^kg[roc|a7? nQnxh]phdpbW}s{i0>#c^c{mZr~xl7: nQmyug\wl|b51&hSnabmnl\gim:8%iThhhnumv\`drf59&hSig|acnf[rgufVhczRm`lm?3(fYcazki`hQxasl\fmpXzhdli0>#c^goegiui}cdbRjfr<-kkhc({bxb`lv dqr,v`vh'er&~bm`n.jt)iidie%b|na}e^fjv*rjx&Uhk""l_dlbficX;;hbxRokdsgpw86+kVljadbv=rrbvqgi>%iTdl}Payk\ma;7$jUcm~Qjn`?2(fYoizUnbo3>,b]kevYnfcohxh|}=1.`[mgtWdofSb{{ptv\v`atWh7; nQgar]nahYh}}z~xR|jgr]a95*dWakxS`{w_nwwtprXzlmxSl3?,b]kevYj}qUdyy~zt^pfcvYe59&hSeo|_sgdg`g:8%iTdl}Prde`ag;7$jUcm~Q}suc>4)eX`hyT~~zm=1.`[mgtWzemxhml_hlsqqYumnyTm0>#c^jbwZuhn}ohoRaztqww[wc`{Vh6<!mPiokw[cokm4Hgmce\tskmc)eXagc\7fSkgce^lbi`;igVidiRhfld]okdbbl%iTecg{a^tbh86+kVceeylPv`n>4)eXag~n~kole^vzt`;7$jUgcljPiokw[cokm4:'oRcjm^vzt`;5$jUfyuQ\7fiqgomkcX{}kli~3?,b]svlkX|pzn1>"l_sgb`Zbbx}bTm0<78-a\v`gcWmo{xeQm=3:;(fYumhnT{dj{h^c>77*dW{ojhRyfduj\f855$jUy\7fyQ\7frhmqmq\7fXi4IN nQ}su]svliua}sTn0MJ,b]qwqYsqyo6_T@L,b]qwqtfeVk6<!mPrrvqehYe59&hS~gb_bmohlunggUhdhmd=@NO(fYr{lUi~lcPbmm`o86+kV\7fxiRlvtd]tad;6$jU~\7fhQmyug\s`d:9%iTy~kPdddbqirXlh~j1<"l_tqf[`ed59&hSx}j_rmep`ed59&hSzkn_vkgpm;3$jU|ioQxievk91*dW~xbxhQkeqvk[d;501&hSz|ftd]gauroWk7945"l_vpjp`YjgmoTm0Y]IUG\BLTT\%iT{\7fg{e^ol``Ye5^XBXHQIISQW(fYpz`~nSzgkti]b964+kV}yeykPwhfwlZd:;;&hSujjvhafbdkndp7x|l|{ao4~65=dgg~ycaQmr`o/fimXelgTkh`Pv6]0(~{03mcem1>18:fjjd:68720hd`n<03=<>bnfh6:>364dhlb845902nbbl2>4?:8`lhf48?546jfn`>22;><l`dj0<918:fjjd:60720hd`n<0;=3>bnfh6:255kioc?658?3mcem1<>>99gmkg;:;437igaa=00:==cagk7>907;ekme942611oeco327<;?aoii58<255kioc?6=8?3mcem1<6>69gmkg;:720hd`n<22=e>bnfh68=7>18:fjjd:497=0hd`n<2<4?aoii5>5;6jfn`>6:2=cagk7:394dhlb82803mcem1617:fjjd:>6>1oecl30?:8`lhe48:546jfnc>25;><l`di0<<18:fjjg:6;720hd`m<06=<>bnfk6:9364dhla840902nbbo2>7?:8`lhe482546jfnc>2=;1<l`di0<07;ekmf947611oecl320<;?aoij589255kio`?668?3mcen1<;>99gmkd;:<437igab=05:==cagh7>:07;ekmf94?611oecl328<4?aoij58546jfnc>04;g<l`di0>?50?:8`lhe4:;5;6jfnc>0:2=cagh78394dhla80803mcen1817:fjjg:06>1oecl38?58`lhe40437iazt`>3:<=cg|~j0<>19:flqqg;98427iazt`>26;?<lf\7f\7fm1?<>89gkprf48>556j`uuc?508>3me~xl2>6?;8`jssi5;<245kotvb84>912ndyyo318<;?air|h6:245kotvb876912ndyyo320<:?air|h69>374dnwwe944601ocxzn<36==>bh}}k7>806;emvpd:5>730hb{{a=04:<=cg|~j0?619:flqqg;:0437iazt`>1:<=cg|~j0>>1b:flqqg;;80;245kotvb867902ndyyo33?:8`jssi5>546j`uuc?1;><lf\7f\7fm1818:flqqg;?720hb{{a=:=<>bh}}k75364dnwwf96912ndyyl311<:?air|k6:=374dnwwf975601ocxzm<01==>bh}}h7=906;emvpg:6=730hb{{b=35:<=cg|~i0<919:flqqd;91427iaztc>2=;><lf\7f\7fn1?19:flqqd;:9427iaztc>15;?<lf\7f\7fn1<=>89gkpre4;9556j`uu`?618>3me~xo2=5?;8`jssj58=245kotva871912ndyyl329<:?air|k695364dnwwf94912ndyyl331<a?air|k68=7>19:flqqd;;8437iaztc>0:==cg|~i0907;emvpg:2611ocxzm<7<;?air|k6<255kotva8=8?3me~xo26>29fjd5<mgh37cilbtko`7=ig?1|il2?>79tad:66?1|il2=>99tad:4294=7zkn<2<5?rce494=7zkm<0<5?rce4;437zkm<283:3=pmk682pNOp2c6?EF\7f9::1J7:51zQ7a?7713nj6<=<2b2;>45>k=qe==951:l24=<13-;;97??1:\7fP0f<6800om7?<33a3<?741jk0_i?51c;94?74;;i;47?<9e08W1e=9k31<7?<33a3<?741m>0h<=?:182>4}T<l0:<44ka;3077e703;85n64vUga>5<62802jv];e;33=?bf2898>n>7:01:g==#n>0o?6X>0781\7fpb3281~h84?;|&gf?713k;8<7>59d86><`|@o<0(k?51228^60=0r;?6<9511821?7?28;1=?4>3;\7f'552=9;k0(>651208 1b=9:;0(h751:&f<?77i2c:nk4?:%fg>4db3gnh6=54i0`g>5<#lm0:nh5adb82?>o6jj0;6)jk:0`f?kbd2;10e<lm:18'`a<6jl1ehn4<;:k251<72-no6<?<;of`>5=<a8;96=4+de8256=ilj0:76g>1083>!bc28;87cjl:398m477290/hi4>129m`f<432c:<k4?:%fg>4743gnh6954i02f>5<#lm0:=>5adb86?>o68m0;6)jk:030?kbd2?10e<>l:18'`a<69:1ehn48;:k24g<72-no6<?<;of`>==<a8>h6=4+de820g=ilj0;76g>4`83>!bc28>i7cjl:098m42?290/hi4>4c9m`f<532c:8:4?:%fg>42e3gnh6>54i065>5<#lm0:8o5adb87?>o6<<0;6)jk:06a?kbd2<10e<:;:18'`a<6<k1ehn49;:k206<72-no6<:m;of`>2=<a8>96=4+de820g=ilj0376g>4083>!bc28>i7cjl:898m427290/hi4>4c9m`f<f32c:?k4?:%fg>42e3gnh6o54i01g>5<#lm0:8o5adb8`?>o6;j0;6)jk:06a?kbd2m10e<=m:18'`a<6<k1ehn4j;:k27d<72-no6<:m;of`>c=<a8926=4+de820g=ilj0:<65f12:94?"cl3;?n6`kc;32?>o6;>0;6)jk:06a?kbd28807d?<6;29 ab=9=h0bim51298m452290/hi4>4c9m`f<6<21b=>:50;&g`?73j2doo7?:;:k216<72-no6<:m;of`>40<3`;>>7>5$ef951d<fmi1=:54i072>5<#lm0:8o5adb82<>=n9<:1<7*kd;37f>hck3;276g>4g83>!bc28>i7cjl:0c8?l73m3:1(ij515`8jae=9k10e<:k:18'`a<6<k1ehn4>c:9j51?=83.oh7?;b:lgg?7c32c:?h4?:%fg>42e3gnh6<k4;h307?6=,mn1=9l4nea95c=<a8i?6=4+de82g6=ilj0;76g>c383>!bc28i87cjl:098m4e6290/hi4>c29m`f<532c:o=4?:%fg>4e43gnh6>54i03f>5<#lm0:=i5adb83?>o69j0;6)jk:03g?kbd2810e<?m:18'`a<69m1ehn4=;:k25d<72-no6<?k;of`>6=<a8;26=4+de825a=ilj0?76g>1983>!bc28;o7cjl:498m470290/hi4>1e9m`f<132c:=;4?:%fg>47c3gnh6:54i036>5<#lm0:=i5adb8;?>o6>m0;6)jk:04`?kbd2910e<8m:18'`a<6>j1ehn4>;:k22<<72-no6<8l;of`>7=<a8<36=4+de822f=ilj0876g>6683>!bc28<h7cjl:598m401290/hi4>6b9m`f<232c::84?:%fg>40d3gnh6;54i047>5<#lm0::n5adb84?>o6>:0;6)jk:04`?kbd2110e<8=:18'`a<6>j1ehn46;:k224<72-no6<8l;of`>d=<a8<;6=4+de822f=ilj0i76g>5d83>!bc28<h7cjl:b98m43c290/hi4>6b9m`f<c32c:9n4?:%fg>40d3gnh6h54i07a>5<#lm0::n5adb8e?>o6=h0;6)jk:04`?kbd28:07d?:9;29 ab=9?i0bim51098m43?290/hi4>6b9m`f<6:21b=8950;&g`?71k2doo7?<;:k213<72-no6<8l;of`>42<3`;>97>5$ef953e<fmi1=854i057>5<#lm0::n5adb822>=n9>91<7*kd;35g>hck3;<76g>7383>!bc28<h7cjl:0:8?l7093:1(ij517a8jae=9010e<9?:18'`a<6>j1ehn4>a:9j53`=83.oh7?9c:lgg?7e32c::h4?:%fg>40d3gnh6<m4;h35e?6=,mn1=;m4nea95a=<a8?m6=4+de822f=ilj0:i65f14694?"cl3;=o6`kc;3e?>o6:l0;66g>b683>>o6:o0;66g>b983>>i60l0;6)jk:0:g?kbd2910c<6l:18'`a<60m1ehn4>;:m2<d<72-no6<6k;of`>7=<g8226=4+de82<a=ilj0876a>8983>!bc282o7cjl:598k4>0290/hi4>8e9m`f<232e:4;4?:%fg>4>c3gnh6;54o0:6>5<#lm0:4i5adb84?>i60=0;6)jk:0:g?kbd2110c<6<:18'`a<60m1ehn46;:m2<7<72-no6<6k;of`>d=<g82:6=4+de82<a=ilj0i76a>7g83>!bc282o7cjl:b98k41b290/hi4>8e9m`f<c32e:;i4?:%fg>4>c3gnh6h54o05`>5<#lm0:4i5adb8e?>i6?k0;6)jk:0:g?kbd28:07b?8a;29 ab=91n0bim51098k41>290/hi4>8e9m`f<6:21d=:650;&g`?7?l2doo7?<;:m232<72-no6<6k;of`>42<3f;<:7>5$ef95=b<fmi1=854o0;6>5<#lm0:4i5adb822>=h90>1<7*kd;3;`>hck3;<76a>9283>!bc282o7cjl:0:8?j7>:3:1(ij519f8jae=9010c<7>:18'`a<60m1ehn4>a:9l5<6=83.oh7?7d:lgg?7e32e:4k4?:%fg>4>c3gnh6<m4;n3;f?6=,mn1=5j4nea95a=<g82;6=4+de82<a=ilj0:i65`16794?"cl3;3h6`kc;3e?>i6io0;6)jk:0cf?kbd2910c<ok:18'`a<6il1ehn4>;:m2eg<72-no6<oj;of`>7=<g8kj6=4+de82e`=ilj0876a>a883>!bc28kn7cjl:598k4g?290/hi4>ad9m`f<232e:m:4?:%fg>4gb3gnh6;54o0c5>5<#lm0:mh5adb84?>i6i<0;6)jk:0cf?kbd2110c<o;:18'`a<6il1ehn46;:m2e6<72-no6<oj;of`>d=<g8k96=4+de82e`=ilj0i76a>a183>!bc28kn7cjl:b98k4?a290/hi4>ad9m`f<c32e:5h4?:%fg>4gb3gnh6h54o0;g>5<#lm0:mh5adb8e?>i61j0;6)jk:0cf?kbd28:07b?6b;29 ab=9ho0bim51098k4?f290/hi4>ad9m`f<6:21d=4750;&g`?7fm2doo7?<;:m2==<72-no6<oj;of`>42<3f;2;7>5$ef95dc<fmi1=854o0`5>5<#lm0:mh5adb822>=h9k?1<7*kd;3ba>hck3;<76a>b583>!bc28kn7cjl:0:8?j7e;3:1(ij51`g8jae=9010c<l=:18'`a<6il1ehn4>a:9l5g7=83.oh7?ne:lgg?7e32e:n=4?:%fg>4gb3gnh6<m4;n3bg?6=,mn1=lk4nea95a=<g8k:6=4+de82e`=ilj0:i65`18494?"cl3;ji6`kc;3e?>d68:0;6<4?:1y'b4<f12B:<?5Gf79le=<722wij?4?:7g94?6|,o;1hk5G1108Lc0<R:<1ov:55;g9b?d=i3i1h7657;49=?{#l00:nl5a4g8:?k37201e4l4?;o;`>5=#i<0j;6*n6;c4?!gf2:1/mo4<;%c`>6=#im087)oj:29'ec<43-h;6>5+b080?!d52:1/n>4<;%`7>6=#j<087)l9:29'f2<43-h36>5+b880?!df2:1/no4<;%``>6=#jm087)lj:29'fc<43-i;6>5+c080?!e52:1/o>4<;%a7>6=#k<087)m9:29'g2<43-i36>5+c880?!ef2:1/oo4<;%a`>6=#km087)mj:39'gc<53-n;6i64$d29b5=#m<0nj6*j6;14?!c02:=0(ho5349'af<53-oo6?5+fg8ea>"6890mi6gj4;29?lg32900eh?50;9je6<722c??7>5;h66>5<<al81<75fe283>>oai3:1(ij5f89m`f<732cm47>5$ef9b<=ilj0:76a70;29 ab=?o1ehn4?;:m4a?6=,mn1;k5adb82?>i0l3:1(ij57g9m`f<532e<o7>5$ef93c=ilj0876a8b;29 ab=?o1ehn4;;:m4e?6=,mn1;k5adb86?>i?13:1(ij57g9m`f<132e347>5$ef93c=ilj0<76a77;29 ab=?o1ehn47;:m;2?6=,mn1;k5adb8:?>i?=3:1(ij57g9m`f<f32e387>5$ef93c=ilj0i76a73;29 ab=?o1ehn4l;:m;6?6=,mn1;k5adb8g?>i?93:1(ij57g9m`f<b32e<57>5$ef93c=ilj0m76a6f;29 ab=1l1ehn4?;:m:`?6=,mn15h5adb82?>if:3:1(ij5a09m`f<732ej<7>5$ef9e4=ilj0:76gid;29 ab=nj1ehn4?;:kef?6=,mn1jn5adb82?>o6l3:1(ij51b9m`f<732c:n7>5$ef95f=ilj0:76g>a;29 ab=9j1ehn4=;:k12?6=,mn1=n5adb80?>o5=3:1(ij51b9m`f<332c987>5$ef95f=ilj0>76g=3;29 ab=9j1ehn49;:k16?6=,mn1=n5adb84?>o593:1(ij51b9m`f<?32c9<7>5$ef95f=ilj0276g>f;29 ab=9j1ehn4n;:k2a?6=,mn1=n5adb8a?>o613:1(ij51b9m`f<d32c<47>5$ef932=ilj0;76g86;29 ab=?>1ehn4>;:k5=?6=,mn1:55adb83?>o1?3:1(ij5699m`f<632c=:7>5$ef92==ilj0976g95;29 ab=>11ehn4<;:k50?6=,mn1:55adb87?>o1;3:1(ij5699m`f<232c<>7>5$ef92==ilj0=76g81;29 ab=>11ehn48;:k44?6=,mn1:55adb8;?>o1n3:1(ij5699m`f<>32c=i7>5$ef92==ilj0j76g9d;29 ab=>11ehn4m;:k5g?6=,mn1:55adb8`?>o1j3:1(ij5699m`f<c32c=m7>5$ef92==ilj0n76g92;29 ab=>11ehn4i;:k6<?6=,mn19:5adb83?>o2>3:1(ij5569m`f<632c>97>5$ef912=ilj0976g:4;29 ab==>1ehn4<;:k67?6=,mn19:5adb87?>o2:3:1(ij5569m`f<232c==7>5$ef912=ilj0=76g90;29 ab==>1ehn48;:k6b?6=,mn19:5adb8;?>o2m3:1(ij5569m`f<>32c>h7>5$ef912=ilj0j76g:c;29 ab==>1ehn4m;:k6f?6=,mn19:5adb8`?>o2i3:1(ij5569m`f<c32c>57>5$ef912=ilj0n76g:1;29 ab==>1ehn4i;:k1f?6=,mn1>l5adb83?>o513:1(ij52`9m`f<632c947>5$ef96d=ilj0976g<4;29 ab=:h1ehn4<;:k07?6=,mn1>l5adb87?>o4:3:1(ij52`9m`f<232c8=7>5$ef96d=ilj0=76g<0;29 ab=:h1ehn48;:k1b?6=,mn1>l5adb8;?>o5m3:1(ij52`9m`f<>32c9h7>5$ef96d=ilj0j76g=c;29 ab=:h1ehn4m;:k13?6=,mn1>l5adb8`?>i>:3:1(ij5909m`f<732e2<7>5$ef9=4=ilj0:76a7f;29 ab=181ehn4=;:m;a?6=,mn15<5adb80?>i?l3:1(ij5909m`f<332e3o7>5$ef9=4=ilj0>76a6b;29 ab=181ehn49;:m:e?6=,mn15<5adb84?>i>13:1(ij5909m`f<?32e247>5$ef9=4=ilj0276a67;29 ab=181ehn4n;:m:2?6=,mn15<5adb8a?>i>=3:1(ij5909m`f<d32e287>5$ef9=4=ilj0o76a63;29 ab=181ehn4j;:m;f?6=,mn15<5adb8e?>o0=3:1(ij5759m`f<732c<?7>5$ef931=ilj0:76smf283>3c=83:p(k?5dg9K554<@o<0V>85cz691?c=n3h1m7m5d;:93?0=13w/h44>b`9m0c<>3g?;645a8`83?k?d291/m84n7:&b2?g03-kj6>5+ac80?!gd2:1/mi4<;%cf>6=#io087)l?:29'f4<43-h96>5+b280?!d32:1/n84<;%`5>6=#j>087)l7:29'f<<43-hj6>5+bc80?!dd2:1/ni4<;%`f>6=#jo087)m?:29'g4<43-i96>5+c280?!e32:1/o84<;%a5>6=#k>087)m7:29'g<<43-ij6>5+cc80?!ed2:1/oi4<;%af>7=#ko097)j?:e:8 `6=n91/i84jf:&f2?503-o<6>94$dc970=#mj097)kk:39'bc<am2.:<=4ie:kf0?6=3`k?6=44id394?=ni:0;66g;3;29?l222900eh<50;9ja6<722cmm7>5$ef9b<=ilj0;76gi8;29 ab=n01ehn4>;:m;4?6=,mn1;k5adb83?>i0m3:1(ij57g9m`f<632e<h7>5$ef93c=ilj0976a8c;29 ab=?o1ehn4<;:m4f?6=,mn1;k5adb87?>i0i3:1(ij57g9m`f<232e357>5$ef93c=ilj0=76a78;29 ab=?o1ehn48;:m;3?6=,mn1;k5adb8;?>i?>3:1(ij57g9m`f<>32e397>5$ef93c=ilj0j76a74;29 ab=?o1ehn4m;:m;7?6=,mn1;k5adb8`?>i?:3:1(ij57g9m`f<c32e3=7>5$ef93c=ilj0n76a89;29 ab=?o1ehn4i;:m:b?6=,mn15h5adb83?>i>l3:1(ij59d9m`f<632ej>7>5$ef9e4=ilj0;76an0;29 ab=i81ehn4>;:ke`?6=,mn1jn5adb83?>oaj3:1(ij5fb9m`f<632c:h7>5$ef95f=ilj0;76g>b;29 ab=9j1ehn4>;:k2e?6=,mn1=n5adb81?>o5>3:1(ij51b9m`f<432c997>5$ef95f=ilj0?76g=4;29 ab=9j1ehn4:;:k17?6=,mn1=n5adb85?>o5:3:1(ij51b9m`f<032c9=7>5$ef95f=ilj0376g=0;29 ab=9j1ehn46;:k2b?6=,mn1=n5adb8b?>o6m3:1(ij51b9m`f<e32c:57>5$ef95f=ilj0h76g88;29 ab=?>1ehn4?;:k42?6=,mn1;:5adb82?>o113:1(ij5699m`f<732c=;7>5$ef92==ilj0:76g96;29 ab=>11ehn4=;:k51?6=,mn1:55adb80?>o1<3:1(ij5699m`f<332c=?7>5$ef92==ilj0>76g82;29 ab=>11ehn49;:k45?6=,mn1:55adb84?>o083:1(ij5699m`f<?32c=j7>5$ef92==ilj0276g9e;29 ab=>11ehn4n;:k5`?6=,mn1:55adb8a?>o1k3:1(ij5699m`f<d32c=n7>5$ef92==ilj0o76g9a;29 ab=>11ehn4j;:k56?6=,mn1:55adb8e?>o203:1(ij5569m`f<732c>:7>5$ef912=ilj0:76g:5;29 ab==>1ehn4=;:k60?6=,mn19:5adb80?>o2;3:1(ij5569m`f<332c>>7>5$ef912=ilj0>76g91;29 ab==>1ehn49;:k54?6=,mn19:5adb84?>o2n3:1(ij5569m`f<?32c>i7>5$ef912=ilj0276g:d;29 ab==>1ehn4n;:k6g?6=,mn19:5adb8a?>o2j3:1(ij5569m`f<d32c>m7>5$ef912=ilj0o76g:9;29 ab==>1ehn4j;:k65?6=,mn19:5adb8e?>o5j3:1(ij52`9m`f<732c957>5$ef96d=ilj0:76g=8;29 ab=:h1ehn4=;:k00?6=,mn1>l5adb80?>o4;3:1(ij52`9m`f<332c8>7>5$ef96d=ilj0>76g<1;29 ab=:h1ehn49;:k04?6=,mn1>l5adb84?>o5n3:1(ij52`9m`f<?32c9i7>5$ef96d=ilj0276g=d;29 ab=:h1ehn4n;:k1g?6=,mn1>l5adb8a?>o5?3:1(ij52`9m`f<d32e2>7>5$ef9=4=ilj0;76a60;29 ab=181ehn4>;:m;b?6=,mn15<5adb81?>i?m3:1(ij5909m`f<432e3h7>5$ef9=4=ilj0?76a7c;29 ab=181ehn4:;:m:f?6=,mn15<5adb85?>i>i3:1(ij5909m`f<032e257>5$ef9=4=ilj0376a68;29 ab=181ehn46;:m:3?6=,mn15<5adb8b?>i>>3:1(ij5909m`f<e32e297>5$ef9=4=ilj0h76a64;29 ab=181ehn4k;:m:7?6=,mn15<5adb8f?>i?j3:1(ij5909m`f<a32c<97>5$ef931=ilj0;76g83;29 ab=?=1ehn4>;:\7fab1<72?o1<7>t$g39`c=O9980Dk84Z249g~2==3o1j7l5a;a9`?>=?3<157s+d882fd=i<o027c;?:89m<d<73g3h6=5+a48b3>"f>3k<7)on:29'eg<43-kh6>5+ae80?!gb2:1/mk4<;%`3>6=#j8087)l=:29'f6<43-h?6>5+b480?!d12:1/n:4<;%`;>6=#j0087)ln:29'fg<43-hh6>5+be80?!db2:1/nk4<;%a3>6=#k8087)m=:29'g6<43-i?6>5+c480?!e12:1/o:4<;%a;>6=#k0087)mn:29'gg<43-ih6>5+ce80?!eb2;1/ok4=;%f3>a><,l:1j=5+e48fb>"b>39<7)k8:258 `g=;<1/in4=;%gg>7=#no0mi6*>018ea>ob<3:17do;:188m`7=831bm>4?::k77?6=3`>>6=44id094?=nm:0;66gia;29 ab=n01ehn4?;:ke<?6=,mn1j45adb82?>i?83:1(ij57g9m`f<732e<i7>5$ef93c=ilj0:76a8d;29 ab=?o1ehn4=;:m4g?6=,mn1;k5adb80?>i0j3:1(ij57g9m`f<332e<m7>5$ef93c=ilj0>76a79;29 ab=?o1ehn49;:m;<?6=,mn1;k5adb84?>i??3:1(ij57g9m`f<?32e3:7>5$ef93c=ilj0276a75;29 ab=?o1ehn4n;:m;0?6=,mn1;k5adb8a?>i?;3:1(ij57g9m`f<d32e3>7>5$ef93c=ilj0o76a71;29 ab=?o1ehn4j;:m4=?6=,mn1;k5adb8e?>i>n3:1(ij59d9m`f<732e2h7>5$ef9=`=ilj0:76an2;29 ab=i81ehn4?;:mb4?6=,mn1m<5adb82?>oal3:1(ij5fb9m`f<732cmn7>5$ef9bf=ilj0:76g>d;29 ab=9j1ehn4?;:k2f?6=,mn1=n5adb82?>o6i3:1(ij51b9m`f<532c9:7>5$ef95f=ilj0876g=5;29 ab=9j1ehn4;;:k10?6=,mn1=n5adb86?>o5;3:1(ij51b9m`f<132c9>7>5$ef95f=ilj0<76g=1;29 ab=9j1ehn47;:k14?6=,mn1=n5adb8:?>o6n3:1(ij51b9m`f<f32c:i7>5$ef95f=ilj0i76g>9;29 ab=9j1ehn4l;:k4<?6=,mn1;:5adb83?>o0>3:1(ij5769m`f<632c=57>5$ef92==ilj0;76g97;29 ab=>11ehn4>;:k52?6=,mn1:55adb81?>o1=3:1(ij5699m`f<432c=87>5$ef92==ilj0?76g93;29 ab=>11ehn4:;:k46?6=,mn1:55adb85?>o093:1(ij5699m`f<032c<<7>5$ef92==ilj0376g9f;29 ab=>11ehn46;:k5a?6=,mn1:55adb8b?>o1l3:1(ij5699m`f<e32c=o7>5$ef92==ilj0h76g9b;29 ab=>11ehn4k;:k5e?6=,mn1:55adb8f?>o1:3:1(ij5699m`f<a32c>47>5$ef912=ilj0;76g:6;29 ab==>1ehn4>;:k61?6=,mn19:5adb81?>o2<3:1(ij5569m`f<432c>?7>5$ef912=ilj0?76g:2;29 ab==>1ehn4:;:k55?6=,mn19:5adb85?>o183:1(ij5569m`f<032c>j7>5$ef912=ilj0376g:e;29 ab==>1ehn46;:k6`?6=,mn19:5adb8b?>o2k3:1(ij5569m`f<e32c>n7>5$ef912=ilj0h76g:a;29 ab==>1ehn4k;:k6=?6=,mn19:5adb8f?>o293:1(ij5569m`f<a32c9n7>5$ef96d=ilj0;76g=9;29 ab=:h1ehn4>;:k1<?6=,mn1>l5adb81?>o4<3:1(ij52`9m`f<432c8?7>5$ef96d=ilj0?76g<2;29 ab=:h1ehn4:;:k05?6=,mn1>l5adb85?>o483:1(ij52`9m`f<032c9j7>5$ef96d=ilj0376g=e;29 ab=:h1ehn46;:k1`?6=,mn1>l5adb8b?>o5k3:1(ij52`9m`f<e32c9;7>5$ef96d=ilj0h76a62;29 ab=181ehn4?;:m:4?6=,mn15<5adb82?>i?n3:1(ij5909m`f<532e3i7>5$ef9=4=ilj0876a7d;29 ab=181ehn4;;:m;g?6=,mn15<5adb86?>i>j3:1(ij5909m`f<132e2m7>5$ef9=4=ilj0<76a69;29 ab=181ehn47;:m:<?6=,mn15<5adb8:?>i>?3:1(ij5909m`f<f32e2:7>5$ef9=4=ilj0i76a65;29 ab=181ehn4l;:m:0?6=,mn15<5adb8g?>i>;3:1(ij5909m`f<b32e3n7>5$ef9=4=ilj0m76g85;29 ab=?=1ehn4?;:k47?6=,mn1;95adb82?>{en<0;6;k50;2x c7=lo1C==<4Hg48^60=kr>197k5f;`9e?e=l321;7859;\7f'`<<6jh1e8k46;o73><=i0h0;7c7l:19'e0<f?2.j:7o8;%cb>6=#ik087)ol:29'ea<43-kn6>5+ag80?!d72:1/n<4<;%`1>6=#j:087)l;:29'f0<43-h=6>5+b680?!d?2:1/n44<;%`b>6=#jk087)ll:29'fa<43-hn6>5+bg80?!e72:1/o<4<;%a1>6=#k:087)m;:29'g0<43-i=6>5+c680?!e?2:1/o44<;%ab>6=#kk087)ml:29'ga<43-in6?5+cg81?!b72m20(h>5f19'a0<bn2.n:7=8;%g4>61<,lk1?85+eb81?!cc2;1/jk4ie:&245<am2cn87>5;hc7>5<<al;1<75fa283>>o3;3:17d:::188m`4=831bi>4?::kee?6=,mn1j45adb83?>oa03:1(ij5f89m`f<632e3<7>5$ef93c=ilj0;76a8e;29 ab=?o1ehn4>;:m4`?6=,mn1;k5adb81?>i0k3:1(ij57g9m`f<432e<n7>5$ef93c=ilj0?76a8a;29 ab=?o1ehn4:;:m;=?6=,mn1;k5adb85?>i?03:1(ij57g9m`f<032e3;7>5$ef93c=ilj0376a76;29 ab=?o1ehn46;:m;1?6=,mn1;k5adb8b?>i?<3:1(ij57g9m`f<e32e3?7>5$ef93c=ilj0h76a72;29 ab=?o1ehn4k;:m;5?6=,mn1;k5adb8f?>i013:1(ij57g9m`f<a32e2j7>5$ef9=`=ilj0;76a6d;29 ab=1l1ehn4>;:mb6?6=,mn1m<5adb83?>if83:1(ij5a09m`f<632cmh7>5$ef9bf=ilj0;76gib;29 ab=nj1ehn4>;:k2`?6=,mn1=n5adb83?>o6j3:1(ij51b9m`f<632c:m7>5$ef95f=ilj0976g=6;29 ab=9j1ehn4<;:k11?6=,mn1=n5adb87?>o5<3:1(ij51b9m`f<232c9?7>5$ef95f=ilj0=76g=2;29 ab=9j1ehn48;:k15?6=,mn1=n5adb8;?>o583:1(ij51b9m`f<>32c:j7>5$ef95f=ilj0j76g>e;29 ab=9j1ehn4m;:k2=?6=,mn1=n5adb8`?>o003:1(ij5769m`f<732c<:7>5$ef932=ilj0:76g99;29 ab=>11ehn4?;:k53?6=,mn1:55adb82?>o1>3:1(ij5699m`f<532c=97>5$ef92==ilj0876g94;29 ab=>11ehn4;;:k57?6=,mn1:55adb86?>o0:3:1(ij5699m`f<132c<=7>5$ef92==ilj0<76g80;29 ab=>11ehn47;:k5b?6=,mn1:55adb8:?>o1m3:1(ij5699m`f<f32c=h7>5$ef92==ilj0i76g9c;29 ab=>11ehn4l;:k5f?6=,mn1:55adb8g?>o1i3:1(ij5699m`f<b32c=>7>5$ef92==ilj0m76g:8;29 ab==>1ehn4?;:k62?6=,mn19:5adb82?>o2=3:1(ij5569m`f<532c>87>5$ef912=ilj0876g:3;29 ab==>1ehn4;;:k66?6=,mn19:5adb86?>o193:1(ij5569m`f<132c=<7>5$ef912=ilj0<76g:f;29 ab==>1ehn47;:k6a?6=,mn19:5adb8:?>o2l3:1(ij5569m`f<f32c>o7>5$ef912=ilj0i76g:b;29 ab==>1ehn4l;:k6e?6=,mn19:5adb8g?>o213:1(ij5569m`f<b32c>=7>5$ef912=ilj0m76g=b;29 ab=:h1ehn4?;:k1=?6=,mn1>l5adb82?>o503:1(ij52`9m`f<532c887>5$ef96d=ilj0876g<3;29 ab=:h1ehn4;;:k06?6=,mn1>l5adb86?>o493:1(ij52`9m`f<132c8<7>5$ef96d=ilj0<76g=f;29 ab=:h1ehn47;:k1a?6=,mn1>l5adb8:?>o5l3:1(ij52`9m`f<f32c9o7>5$ef96d=ilj0i76g=7;29 ab=:h1ehn4l;:m:6?6=,mn15<5adb83?>i>83:1(ij5909m`f<632e3j7>5$ef9=4=ilj0976a7e;29 ab=181ehn4<;:m;`?6=,mn15<5adb87?>i?k3:1(ij5909m`f<232e2n7>5$ef9=4=ilj0=76a6a;29 ab=181ehn48;:m:=?6=,mn15<5adb8;?>i>03:1(ij5909m`f<>32e2;7>5$ef9=4=ilj0j76a66;29 ab=181ehn4m;:m:1?6=,mn15<5adb8`?>i><3:1(ij5909m`f<c32e2?7>5$ef9=4=ilj0n76a7b;29 ab=181ehn4i;:k41?6=,mn1;95adb83?>o0;3:1(ij5759m`f<632wxh;4?:93x94642h201k<51e9>b7<6n27m>7?j;<d1>4?<5o81>o52f381`>;a:38h70h=:3589c4==116j?4:6:?e6?3234l968:4=g0916=:n;0>>63i2;42?8`52?:01k<5689>b7<1?27m>789;<d1>33<5o81:952f3857>;a:3=970h=:6389c4=?<16j?483:?e6?1?34l96:84=g09a4=:n;0n>63i2;g0?8`52l>01k=51e9>b6<6n27m?7?j;<d0>4?<5o91>o52f281`>;a;38h70h<:3589c5==116j>4:6:?e7?3234l868:4=g1916=:n:0>>63i3;42?8`42?:01k=5689>b6<1?27m?789;<d0>33<5o91:952f2857>;a;3=970h<:6389c5=?<16j>483:?e7?1?34l86:84=g19a4=:n:0n>63i3;g0?8`42l>01k:51e9>b1<6n27m87?j;<d7>4?<5o>1>o52f581`>;a<38h70h;:3589c2==116j94:6:?e0?3234l?68:4=g6916=:n=0>>63i4;42?8`32?:01k:5689>b1<1?27m8789;<d7>33<5o>1:952f5857>;a<3=970h;:6389c2=?<16j9483:?e0?1?34l?6:84=g69a4=:n=0n>63i4;g0?8`32l>01k;51e9>b0<6n27m97?j;<d6>4?<5o?1>o52f481`>;a=38h70h::3589c3==116j84:6:?e1?3234l>68:4=g7916=:n<0>>63i5;42?8`22?:01k;5689>b0<1?27m9789;<d6>33<5o?1:952f4857>;a=3=970h::6389c3=?<16j8483:?e1?1?34l>6:84=g79a4=:n<0n>63i5;g0?8`22l>0q~?66;296~X61?16j?47b:\7fp5d7=838pR<o>;<d1><5<uz;jo7>52z\2ef=:n;0286s|1c294?4|V8h;70h=:878yv7e93:1>vP>b09>b7<>>2wx=o<50;0xZ4d534l96494}r3a7?6=:rT:n>52f38:<>{t9k>1<7<t^0`7?8`52030q~?m5;296~X6j<16j>47b:\7fp5g0=838pR<l9;<d0><5<uz;2;7>52z\2=2=:n:0286s|18:94?4|V83370h<:878yv7>13:1>vP>989>b6<>>2wx=4o50;0xZ4?f34l86494}r3:f?6=:rT:5o52f28:<>{t90i1<7<t^0;`?8`42030q~?6d;296~X61m16j947b:\7fp5<c=838pR<7j;<d7><5<uz;2j7>52z\2=c=:n=0286s|1`294?4|V8k;70h;:878yv7f:3:1>vP>a39>b1<>>2wx=l=50;0xZ4g434l?6494}r3b0?6=:rT:m952f58:<>{t9h?1<7<t^0c6?8`32030q~?n6;296~X6i?16j847b:\7fp5d1=838pR<o8;<d6><5<uz;j47>52z\2e==:n<0286s|1`;94?4|V8k270h::878yv7fi3:1>vP>a`9>b0<>>2wx=ll50;0xZ4ge34l>6494}r3b`?6=:rT:mi52f48:<>{t9hl1<7<t^0ce?8`22030q~?85;296~X6?<16j?489:\7fp5=6=838pR<6?;<d1>=7<uz;3n7>52z\2<g=:n;03>6s|19d94?4|V82m70h=:918yv7>83:1>vP>919>b7<?<2wx=4?50;0xZ4?634l965;4}r3:6?6=:rT:5?52f38;2>{t9091<7<t^0;0?8`521=0q~?64;296~X61=16j>489:\7fp5<3=838pR<7:;<d0>=7<uz;<:7>52z\233=:n:03>6s|16594?4|V8=<70h<:918yv7003:1>vP>799>b6<?<2wx=:750;0xZ41>34l865;4}r34e?6=:rT:;l52f28;2>{t9>h1<7<t^05a?8`421=0q~?8c;296~X6?j16j9489:\7fp52b=838pR<9k;<d7>=7<uz;<i7>52z\23`=:n=03>6s|16d94?4|V8=m70h;:918yv7?93:1>vP>809>b1<?<2wx=5<50;0xZ4>534l?65;4}r3;7?6=:rT:4>52f58;2>{t91>1<7<t^0:7?8`321=0q~?75;296~X60<16j8489:\7fp5=0=838pR<69;<d6>=7<uz;3;7>52z\2<2=:n<03>6s|19:94?4|V82370h::918yv7?13:1>vP>889>b0<?<2wx=5o50;0xZ4>f34l>65;4}r3;g?6=:rT:4n52f48;2>{t91o1<7<t^0:f?8`221=0q~?m8;291~X6j116j?4n4:?e7?g334l?6l:4=g79e1=z{88m6=4:{_31b>;a:3>>70h<:5789c2=<<16j84;5:\7fp5g1=83?pR<l8;<d1>d5<5o91m>52f58b7>;a=3k87p}>2d83>0}Y9;o01k<5429>b6<3;27m87:<;<d6>15<uz;>87>52z\211=:n;0=>6s|14d94?4|V8?m70h=:7c8yv71i3:1>vP>6`9>b7<1j2wx=;k50;0xZ40b34l96;m4}r35b?6=:rT::k52f385`>{t9>:1<7<t^053?8`52?o0q~?81;296~X6?816j?49f:\7fp524=838pR<9=;<d1>26<uz;<?7>52z\236=:n:0=>6s|16694?4|V8=?70h<:7c8yv72=3:1>vP>549>b6<1j2wx=8850;0xZ43134l86;m4}r363?6=:rT:9:52f285`>{t9<21<7<t^07;?8`42?o0q~?:9;296~X6=016j>49f:\7fp50g=838pR<;n;<d0>26<uz;>n7>52z\21g=:n=0=>6s|14a94?4|V8?h70h;:7c8yv72l3:1>vP>5e9>b1<1j2wx=8k50;0xZ43b34l?6;m4}r354?6=:rT::=52f585`>{t9?;1<7<t^042?8`32?o0q~?92;296~X6>;16j949f:\7fp535=838pR<8<;<d7>26<uz;=87>52z\221=:n<0=>6s|17794?4|V8<>70h::7c8yv71>3:1>vP>679>b0<1j2wx=;950;0xZ40034l>6;m4}r35<?6=:rT::552f485`>{t9?31<7<t^04:?8`22?o0q~?9b;296~X6>k16j849f:\7fp53b=838pR<8k;<d6>26<uz;:97>55z\250=:n;09i63i3;0f?8`32;o01k;52d9~w471290>wS?>6:?e6?4a34l86?h4=g696c=:n<09j6s|10594?3|V8;<70h=:2289c5=;916j94<0:?e1?573ty:=54?:4y]54><5o81?<52f2805>;a<39:70h::238yv7613:19vP>189>b7<4:27m?7==;<d7>64<5o?1??5rs03b>5<2sW;:m63i2;10?8`42:901k:5329>b0<4;2wx=<l50;7xZ47e34l96>:4=g1971=:n=08863i5;17?xu69j0;68uQ10a89c4=:116j>4=8:?e0?4?34l>6?64}r32a?6==rT:=h52f381=>;a;38270h;:3;89c3=:01v\7f<m?:180\7f[7d827m>7hk;<d1>cd<uz;h=7>53z\2g4=:n:0mh63i3;da?xu6k;0;6>uQ1b089c2=nm16j94ib:\7fp5f2=839pR<m;;<d6>cb<5o?1jo5rs010>5<5sW;8?63i2;72?xu6;l0;6?uQ12g89c4==01v\7f<:6:181\7f[73127m>7;n;|q20a<72;qU=9j4=g091g=z{8>n6=4={_37a>;a:3?h7p}>4g83>7}Y9=l01k<55e9~w4372909wS?:0:?e6?3b3ty:9<4?:3y]507<5o819k5rs071>5<5sW;>>63i3;72?xu6=:0;6?uQ14189c5==01v\7f<=;:181\7f[74<27m?7;n;|q270<72;qU=>;4=g191g=z{89=6=4={_302>;a;3?h7p}>3683>7}Y9:=01k=55e9~w45?2909wS?<8:?e7?3b3ty:?44?:3y]56?<5o919k5rs01b>5<5sW;8m63i4;72?xu6;k0;6?uQ12`89c2==01v\7f<=l:181\7f[74k27m87;n;|q27a<72;qU=>j4=g691g=z{89m6=4={_30b>;a<3?h7p}>4183>7}Y9=:01k:55e9~w4262909wS?;1:?e0?3b3ty:8?4?:3y]514<5o>19k5rs060>5<5sW;??63i5;72?xu6<=0;6?uQ15689c3==01v\7f<:::181\7f[73=27m97;n;|q203<72;qU=984=g791g=z{8><6=4={_373>;a=3?h7p}>4983>7}Y9=201k;55e9~w42f2909wS?;a:?e1?3b3ty:8n4?:3y]51e<5o?19k5rs02a>5<2sW;;n63i2;03?8`42;:01k:5219>b0<582wx==m50;7xZ46d34l96??4=g1964=:n=09=63i5;02?xu68m0;68uQ11f89c4=:;16j>4=2:?e0?4534l>6?<4}r33a?6==rT:<h52f3817>;a;38870h;:3189c3=::1v\7f<>i:186\7f[77n27m>7<;;<d0>72<5o>1>952f4810>{t98:1<7;t^033?8`52;?01k=5249>b1<5=27m97<:;|q254<72<qU=<?4=g0963=:n:09:63i4;05?8`22;<0q~?>2;291~X69;16j?4>a:?e7?7f34l?6<o4=g795d=z{8;?6=4:{_320>;a:3;i70h<:0`89c2=9k16j84>b:\7fp5gd=839pR<lm;<d1>cg<5o81j55rs0``>5<4sW;io63i3;db?8`42o20q~?md;297~X6jm16j94ia:?e0?`?3ty:nk4?:2y]5g`<5o?1jl52f48e<>{zf;<<6=4>{Id5?xh5>10;6<uGf79~j70>290:wEh9;|l12d<728qCj;5rn34a>5<6sAl=7p`=6b83>4}On?1vb?8k:182\7fM`13td9:h4?:0yKb3=zf;<m6=4>{Id5?xh5?90;6<uGf79~j716290:wEh9;|l137<728qCj;5rn350>5<6sAl=7p`=7583>4}On?1vb?9::182\7fM`13td9;;4?:0yKb3=zf;=<6=4>{Id5?xh5?10;6<uGf79~j71>290:wEh9;|l13d<728qCj;5rn35a>5<6sAl=7p`=7b83>4}On?1vb?9k:182\7fM`13td9;h4?:0yKb3=zf;=m6=4>{Id5?xh5090;6<uGf79~j7>6290:wEh9;|l1<7<728qCj;5rn3:0>5<6sAl=7p`=8583>4}On?1vb?6::182\7fM`13td94;4?:0yKb3=zf;2<6=4>{Id5?xh5010;6<uGf79~j7>>290:wEh9;|l1<d<728qCj;5rn3:a>5<6sAl=7p`=8b83>4}On?1vb?6k:182\7fM`13td94h4?:0yKb3=zf;2m6=4>{Id5?xh5190;6<uGf79~j7?6290:wEh9;|l1=7<728qCj;5rn3;0>5<6sAl=7p`=9583>4}On?1vb?7::182\7fM`13td95;4?:0yKb3=zf;3<6=4>{Id5?xh5110;6<uGf79~j7?>290:wEh9;|l1=d<728qCj;5rn3;a>5<6sAl=7p`=9b83>4}On?1vb?7k:182\7fM`13td95h4?:0yKb3=zf;3m6=4>{Id5?xh5i90;6<uGf79~j7g6290:wEh9;|l1e7<728qCj;5rn3c0>5<6sAl=7p`=a583>4}On?1vb?o::182\7fM`13td9m;4?:0yKb3=zf;k<6=4>{Id5?xh5i10;6<uGf79~j7g>290:wEh9;|l1ed<728qCj;5rn3ca>5<6sAl=7p`=ab83>4}On?1vb?ok:182\7fM`13td9mh4?:0yKb3=zf;km6=4>{Id5?xh5j90;6<uGf79~j7d6290:wEh9;|l1f7<728qCj;5rn3`0>5<6sAl=7p`=b583>4}On?1vb?l::182\7fM`13td9n;4?:0yKb3=zf;h<6=4>{Id5?xh5j10;6<uGf79~j7d>290:wEh9;|l1fd<728qCj;5rn3`a>5<6sAl=7p`=bb83>4}On?1vb?lk:182\7fM`13td9nh4?:0yKb3=zf;hm6=4>{Id5?xh5k90;6<uGf79~j7e6290:wEh9;|l1g7<728qCj;5rn3a0>5<6sAl=7p`=c583>4}On?1vb?m::182\7fM`13td9o;4?:0yKb3=zf;i<6=4>{Id5?xh5k10;6<uGf79~j7e>290:wEh9;|l1gd<728qCj;5rn3aa>5<6sAl=7p`=cb83>4}On?1vb?mk:182\7fM`13td9oh4?:0yKb3=zf;im6=4>{Id5?xh5l90;6<uGf79~j7b6290:wEh9;|l1`7<728qCj;5rn3f0>5<6sAl=7p`=d583>4}On?1vb?j::182\7fM`13td9h;4?:0yKb3=zf;n<6=4>{Id5?xh5l10;6<uGf79~j7b>290:wEh9;|l1`d<728qCj;5rn3fa>5<6sAl=7p`=db83>4}On?1vb?jk:182\7fM`13td9hh4?:0yKb3=zf;nm6=4>{Id5?xh5m90;6<uGf79~j7c6290:wEh9;|l1a7<728qCj;5rn3g0>5<6sAl=7p`=e583>4}On?1vb?k::182\7fM`13td9i;4?:0yKb3=zf;o<6=4>{Id5?xh5m10;6<uGf79~j7c>290:wEh9;|l1ad<728qCj;5rn3ga>5<6sAl=7p`=eb83>4}On?1vb?kk:182\7fM`13td9ih4?:0yKb3=zf;om6=4>{Id5?xh5n90;6<uGf79~j7`6290:wEh9;|l1b7<728qCj;5rn3d0>5<6sAl=7p`=f583>4}On?1vb?h::182\7fM`13td9j;4?:0yKb3=zf;l<6=4>{Id5?xh5n10;6<uGf79~j7`>290:wEh9;|l1bd<728qCj;5rn3da>5<6sAl=7p`=fb83>4}On?1vb?hk:182\7fM`13td9jh4?:0yKb3=zf;lm6=4>{Id5?xh4890;6<uGf79~j666290:wEh9;|l047<728qCj;5rn220>5<6sAl=7p`<0583>4}On?1vb>>::182\7fM`13twvqMNL{2c6>a7al:;9<pNOBz2~DEV|uIJ
\ No newline at end of file
diff --git a/hw/ipcore_dir/control_bram.vhd b/hw/ipcore_dir/control_bram.vhd
deleted file mode 100644 (file)
index 683ab5f..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
---------------------------------------------------------------------------------
---    This file is owned and controlled by Xilinx and must be used solely     --
---    for design, simulation, implementation and creation of design files     --
---    limited to Xilinx devices or technologies. Use with non-Xilinx          --
---    devices or technologies is expressly prohibited and immediately         --
---    terminates your license.                                                --
---                                                                            --
---    XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY    --
---    FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES.  BY    --
---    PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE             --
---    IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS      --
---    MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY      --
---    CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY       --
---    RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY       --
---    DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE   --
---    IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR          --
---    REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF         --
---    INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A   --
---    PARTICULAR PURPOSE.                                                     --
---                                                                            --
---    Xilinx products are not intended for use in life support appliances,    --
---    devices, or systems.  Use in such applications are expressly            --
---    prohibited.                                                             --
---                                                                            --
---    (c) Copyright 1995-2013 Xilinx, Inc.                                    --
---    All rights reserved.                                                    --
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
--- You must compile the wrapper file control_bram.vhd when simulating
--- the core, control_bram. When compiling the wrapper file, be sure to
--- reference the XilinxCoreLib VHDL simulation library. For detailed
--- instructions, please refer to the "CORE Generator Help".
-
--- The synthesis directives "translate_off/translate_on" specified
--- below are supported by Xilinx, Mentor Graphics and Synplicity
--- synthesis tools. Ensure they are correct for your synthesis tool(s).
-
-LIBRARY ieee;
-USE ieee.std_logic_1164.ALL;
--- synthesis translate_off
-LIBRARY XilinxCoreLib;
--- synthesis translate_on
-ENTITY control_bram IS
-  PORT (
-    clka : IN STD_LOGIC;
-    ena : IN STD_LOGIC;
-    wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
-    addra : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
-    dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
-    douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
-    clkb : IN STD_LOGIC;
-    enb : IN STD_LOGIC;
-    web : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
-    addrb : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
-    dinb : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
-    doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
-  );
-END control_bram;
-
-ARCHITECTURE control_bram_a OF control_bram IS
--- synthesis translate_off
-COMPONENT wrapped_control_bram
-  PORT (
-    clka : IN STD_LOGIC;
-    ena : IN STD_LOGIC;
-    wea : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
-    addra : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
-    dina : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
-    douta : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
-    clkb : IN STD_LOGIC;
-    enb : IN STD_LOGIC;
-    web : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
-    addrb : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
-    dinb : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
-    doutb : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
-  );
-END COMPONENT;
-
--- Configuration specification
-  FOR ALL : wrapped_control_bram USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
-    GENERIC MAP (
-      c_addra_width => 9,
-      c_addrb_width => 9,
-      c_algorithm => 0,
-      c_axi_id_width => 4,
-      c_axi_slave_type => 0,
-      c_axi_type => 1,
-      c_byte_size => 8,
-      c_common_clk => 0,
-      c_default_data => "0",
-      c_disable_warn_bhv_coll => 0,
-      c_disable_warn_bhv_range => 0,
-      c_enable_32bit_address => 0,
-      c_family => "spartan6",
-      c_has_axi_id => 0,
-      c_has_ena => 1,
-      c_has_enb => 1,
-      c_has_injecterr => 0,
-      c_has_mem_output_regs_a => 0,
-      c_has_mem_output_regs_b => 0,
-      c_has_mux_output_regs_a => 0,
-      c_has_mux_output_regs_b => 0,
-      c_has_regcea => 0,
-      c_has_regceb => 0,
-      c_has_rsta => 0,
-      c_has_rstb => 0,
-      c_has_softecc_input_regs_a => 0,
-      c_has_softecc_output_regs_b => 0,
-      c_init_file => "BlankString",
-      c_init_file_name => "no_coe_file_loaded",
-      c_inita_val => "0",
-      c_initb_val => "0",
-      c_interface_type => 0,
-      c_load_init_file => 0,
-      c_mem_type => 2,
-      c_mux_pipeline_stages => 0,
-      c_prim_type => 3,
-      c_read_depth_a => 288,
-      c_read_depth_b => 288,
-      c_read_width_a => 32,
-      c_read_width_b => 32,
-      c_rst_priority_a => "CE",
-      c_rst_priority_b => "CE",
-      c_rst_type => "SYNC",
-      c_rstram_a => 0,
-      c_rstram_b => 0,
-      c_sim_collision_check => "ALL",
-      c_use_bram_block => 0,
-      c_use_byte_wea => 1,
-      c_use_byte_web => 1,
-      c_use_default_data => 1,
-      c_use_ecc => 0,
-      c_use_softecc => 0,
-      c_wea_width => 4,
-      c_web_width => 4,
-      c_write_depth_a => 288,
-      c_write_depth_b => 288,
-      c_write_mode_a => "WRITE_FIRST",
-      c_write_mode_b => "WRITE_FIRST",
-      c_write_width_a => 32,
-      c_write_width_b => 32,
-      c_xdevicefamily => "spartan6"
-    );
--- synthesis translate_on
-BEGIN
--- synthesis translate_off
-U0 : wrapped_control_bram
-  PORT MAP (
-    clka => clka,
-    ena => ena,
-    wea => wea,
-    addra => addra,
-    dina => dina,
-    douta => douta,
-    clkb => clkb,
-    enb => enb,
-    web => web,
-    addrb => addrb,
-    dinb => dinb,
-    doutb => doutb
-  );
--- synthesis translate_on
-
-END control_bram_a;
index 8172f8a0d8fb0b7bca21dc51c28ef1001a785f30..b4cd1776e92b15d335d06638815aadbeeec70609 100644 (file)
@@ -3,71 +3,36 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
 
 -- IRC reader module
 
 entity irc_reader is
        port
        (
-    clk       : in std_logic;
-    reset     : in std_logic;
-    a0, b0    : in std_logic;
-               index0    : in std_logic;
-               mark0     : in std_logic;
-
-    qcount    : out std_logic_vector (31 downto 0);
-    ab_event  : out std_logic;
-    ab_error  : out std_logic;
-               out_index : out std_logic;
-               out_mark  : out std_logic
+    clk          : in std_logic;
+    reset        : in std_logic;
+    a0, b0       : in std_logic;
+               index0       : in std_logic;
+               mark0        : in std_logic;
+
+    qcount       : out std_logic_vector (31 downto 0);
+               qcount_index : out std_logic_vector (31 downto 0);
+    ab_event     : out std_logic;
+    ab_error     : out std_logic;
+               out_mark     : out std_logic
   );
 end irc_reader;
 
-architecture Behavioral of irc_reader is
-       component qcounter
-       port
-       (
-               clk      : in std_logic;
-               reset    : in std_logic;
-               a0, b0   : in std_logic;
-
-               a_rise   : out std_logic;
-               a_fall   : out std_logic;
-               b_rise   : out std_logic;
-               b_fall   : out std_logic;
-
-               qcount   : out std_logic_vector (31 downto 0);
-               ab_event : out std_logic;
-               ab_error : out std_logic
-       );
-       end component;
-
-       component dff
-       port
-       (
-               clk   : in std_logic;
-               reset : in std_logic;
-               d     : in std_logic;
-               q     : out std_logic
-       );
-  end component;
+architecture rtl of irc_reader is
 
        begin
 
-       dff_index: dff
+       dff_mark: dff2
        port map
        (
                clk => clk,
-               reset => reset,
-               d => index0,
-               q => out_index
-       );
-
-       dff_mark: dff
-       port map
-       (
-               clk => clk,
-               reset => reset,
+               reset => '0',
                d => mark0,
                q => out_mark
        );
@@ -79,7 +44,9 @@ architecture Behavioral of irc_reader is
                reset => reset,
                a0 => a0,
                b0 => b0,
+               index0 => index0,
                qcount => qcount,
+               qcount_index => qcount_index,
                ab_event => ab_event,
                ab_error => ab_error,
                a_rise => open,
@@ -88,5 +55,4 @@ architecture Behavioral of irc_reader is
                b_fall => open
        );
 
-end Behavioral;
-
+end rtl;
index 21029ca2b0cdf280ae6c42beb73142e7e6ae1229..50a215c0af69ded8730ff2e47fbb532d984cc442 100644 (file)
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
 
 -- IRC register: connects IRC output to memory bus
 
@@ -15,7 +16,7 @@ entity irc_register is
                index0      : in std_logic;
                mark0       : in std_logic;
 
-               -- Data bus
+               -- Data bus for Master CPU
                data_in    : in std_logic; -- 1 bit input
                data_out   : out std_logic_vector(31 downto 0);
 
@@ -33,27 +34,24 @@ architecture Behavioral of irc_register is
        signal qcount_error      : std_logic;
        signal qcount            : std_logic_vector (31 downto 0);
        signal qcount_index      : std_logic_vector (31 downto 0);
-       signal qcount_index_prev : std_logic_vector (31 downto 0);
        signal ab_event          : std_logic;
        signal ab_error          : std_logic;
-       signal old_index         : std_logic;
-       signal out_index         : std_logic;
        signal out_mark          : std_logic;
 
        component irc_reader
        port
        (
-               clk       : in std_logic;
-               reset     : in std_logic;
-               a0, b0    : in std_logic;
-               index0    : in std_logic;
-               mark0     : in std_logic;
-
-               qcount    : out std_logic_vector (31 downto 0);
-               ab_event  : out std_logic;
-               ab_error  : out std_logic;
-               out_index : out std_logic;
-               out_mark  : out std_logic
+               clk          : in std_logic;
+               reset        : in std_logic;
+               a0, b0       : in std_logic;
+               index0       : in std_logic;
+               mark0        : in std_logic;
+
+               qcount       : out std_logic_vector (31 downto 0);
+               qcount_index : out std_logic_vector (31 downto 0);
+               ab_event     : out std_logic;
+               ab_error     : out std_logic;
+               out_mark     : out std_logic
        );
        end component;
 
@@ -69,9 +67,9 @@ begin
                index0 => index0,
                mark0 => mark0,
                qcount => qcount,
+               qcount_index => qcount_index,
                ab_event => ab_event,
                ab_error => ab_error,
-               out_index => out_index,
                out_mark => out_mark
        );
 
@@ -84,59 +82,34 @@ begin
                        else
                                qcount_error <= qcount_error or ab_error;
                        end if;
-
-                       old_index <= out_index;
-                       qcount_index_prev <= qcount_index;
                end if;
 
        end process;
 
-       signals: process(reset, old_index, out_index, qcount, qcount_index_prev)
-       begin
-
-               if reset = '0' and old_index = '0' and out_index = '1' then
-                       qcount_index <= qcount;
-               elsif reset = '1' then
-                       qcount_index <= (others => '0');
-               else
-                       qcount_index <= qcount_index_prev;
-               end if;
-
-       end process;
 
        memory_bus: process(ce, rd, qcount, qcount_index, qcount_error, ab_event, ab_error, out_mark)
        begin
 
                -- Reset signals
-               ta <= '1';
+               ta <= rd;
                data_out <= (others => 'X');
 
                -- Check chip enable
                case ce is
                        when "00" =>
-                               if rd = '0' then
-                                       data_out <= qcount;
-                                       ta <= '0';
-                               end if;
+                               data_out <= qcount;
 
                        when "01" =>
-                               if rd = '0' then
-                                       data_out <= qcount_index;
-                                       ta <= '0';
-                               end if;
+                               data_out <= qcount_index;
 
                        when "10" =>
-                               if rd = '0' then
-                                       data_out(0) <= ab_event;
-                                       data_out(1) <= ab_error;
-                                       data_out(2) <= qcount_error;
-                                       data_out(3) <= out_mark;
-                                       data_out(31 downto 4) <= (others => '0');
-                                       ta <= '0';
-                               end if;
-
-                       when others =>
-                               data_out <= (others => 'X');
+                               data_out(0) <= ab_event;
+                               data_out(1) <= ab_error;
+                               data_out(2) <= qcount_error;
+                               data_out(3) <= out_mark;
+                               data_out(31 downto 4) <= (others => '0');
+
+                       when others => NULL;
 
                end case;
 
index 170076423190767ebe72329b0a36bd00f82e36b2..73ed939e907012f1b47912aeef73739f9a493247 100644 (file)
@@ -6,10 +6,10 @@ CONFIG VCCAUX  = 3.3;
 # ====================================================================
 
 # Clock
-NET CLK_CPU             PERIOD = 13.8ns HIGH 50%;
-NET CLK_CPU             LOC = P15  | IOSTANDARD = LVCMOS33;
-#NET CLK_50M             PERIOD = 20.0ns HIGH 50%;
-#NET CLK_50M             LOC = P14  | IOSTANDARD = LVCMOS33;
+#NET CLK_CPU             PERIOD = 13.8ns HIGH 50%;
+#NET CLK_CPU             LOC = P15  | IOSTANDARD = LVCMOS33;
+NET CLK_50M             PERIOD = 20.0ns HIGH 50%;
+NET CLK_50M             LOC = P14  | IOSTANDARD = LVCMOS33;
 
 # Reset (active LOW)
 NET INIT                LOC = P39  | IOSTANDARD = LVCMOS33;
diff --git a/hw/lx-rocon_firmware/firmware.c b/hw/lx-rocon_firmware/firmware.c
new file mode 100644 (file)
index 0000000..e12a76a
--- /dev/null
@@ -0,0 +1,83 @@
+/* Firmware file for lx-rocon tumbl coprocessor */
+
+#include <stdint.h>
+
+typedef struct
+{
+       int16_t p;
+       int16_t i;
+       int32_t irc_period;
+       int16_t req_current;
+       int16_t acc_dev;
+       int16_t max_acc;
+} axis_settings;
+
+typedef struct
+{
+       /* Input */
+       int16_t current;
+       int32_t irc;
+       int32_t irc_last;
+       int32_t irc_norm;
+
+       /* Output */
+       uint16_t pwm[3];
+} axis_io;
+
+axis_settings a_settings;
+
+axis_io a_io;
+int32_t irc_a_reg;
+int16_t current_a_reg;
+uint32_t count;
+int16_t phase_table[1][1];
+
+void init_defvals()
+{
+       a_settings.p = 20;
+       a_settings.i = 2;
+       a_settings.irc_period = 7000;
+       a_settings.req_current = 500;
+       a_settings.acc_dev = 0;
+}
+
+void update_axis(axis_settings *settings, axis_io* io)
+{
+       int i;
+       int16_t dev;
+       int32_t mag, irc_diff;
+
+       dev = settings->req_current - io->current;
+       settings->acc_dev += dev;
+
+       if (settings->acc_dev > settings->max_acc)
+               settings->acc_dev = settings->max_acc;
+       else if (-(settings->acc_dev) <= -(settings->max_acc))
+               settings->acc_dev = -(settings->max_acc);
+
+       mag = settings->acc_dev * settings->i + dev * settings->p;
+
+       irc_diff = io->irc - io->irc_last;
+       io->irc_last = io->irc;
+       io->irc_norm += irc_diff;
+
+       if (io->irc_norm > settings->irc_period)
+               io->irc_norm -= settings->irc_period;
+       else if (io->irc_norm < 0)
+               io->irc_norm += settings->irc_period;
+
+       for (i = 0; i < 3; i++)
+               io->pwm[i] = (uint16_t)((mag * phase_table[/*i*/ 0][/*irc_norm*/ 0]) >> 16);
+}
+
+void main()
+{
+       while (1)
+       {
+               update_axis(&a_settings, &a_io);
+               a_io.irc = irc_a_reg;
+               a_io.current = current_a_reg;
+               count++;
+       }
+}
+
diff --git a/hw/lx-rocon_firmware/start.S b/hw/lx-rocon_firmware/start.S
new file mode 100644 (file)
index 0000000..b3b34c6
--- /dev/null
@@ -0,0 +1,66 @@
+/* LX ROCON firmware startup file */
+
+.globl _main
+.align 2
+
+_main:
+
+       /* Stack pointer */
+       addi     r1, r0, 0xFFC
+
+       /* Other register values are not initialized to 0 */
+       addi     r2, r0, 0
+       addi     r3, r0, 0
+       addi     r4, r0, 0
+       addi     r5, r0, 0
+       addi     r6, r0, 0
+       addi     r7, r0, 0
+       addi     r8, r0, 0
+       addi     r9, r0, 0
+       addi     r10, r0, 0
+       addi     r11, r0, 0
+       addi     r12, r0, 0
+       addi     r13, r0, 0
+       addi     r14, r0, 0
+       addi     r15, r0, 0
+       addi     r16, r0, 0
+       addi     r17, r0, 0
+       addi     r18, r0, 0
+       addi     r19, r0, 0
+       addi     r20, r0, 0
+       addi     r21, r0, 0
+       addi     r22, r0, 0
+       addi     r23, r0, 0
+       addi     r24, r0, 0
+       addi     r25, r0, 0
+       addi     r26, r0, 0
+       addi     r27, r0, 0
+       addi     r28, r0, 0
+       addi     r29, r0, 0
+       addi     r30, r0, 0
+       addi     r31, r0, 0
+
+       /* reset data */
+       addi     r6, r0, _sdata
+       addi     r7, r0, _edata
+       rsub     r18, r6, r7
+       blei     r18, .Lenddata
+.Lloopdata:
+       swi      r0, r6, 0
+       addi     r6, r6, 4
+       rsub     r18, r6, r7
+       bgti     r18, .Lloopdata
+       or       r0, r0, r0
+.Lenddata:
+       /* Init default values */
+       brlid    r15, init_defvals
+       addi     r31, r0, 20
+       or       r0, r0, r0
+
+       /* Run program */
+       brlid    r15, main
+       or        r0, r0, r0
+
+       /* End of program */
+       bri       0x00
+       or        r0, r0, r0
diff --git a/hw/lx-rocon_firmware/utils b/hw/lx-rocon_firmware/utils
new file mode 120000 (symlink)
index 0000000..a755350
--- /dev/null
@@ -0,0 +1 @@
+../../submodule/tumbl/utils
\ No newline at end of file
diff --git a/hw/lx-rocon_tumbl/lx_rocon_dmem.vhd b/hw/lx-rocon_tumbl/lx_rocon_dmem.vhd
new file mode 100644 (file)
index 0000000..b9e3f58
--- /dev/null
@@ -0,0 +1,72 @@
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.mbl_Pkg.all;
+use work.lx_rocon_pkg.all;
+
+-- 4 kB data memory for Thumbl core
+-- To be flashed from the Master CPU
+
+entity lx_rocon_dmem is
+       port
+       (
+               -- Memory wiring for Tumbl
+               clk_i  : in std_logic;
+               ce_i   : in std_logic;
+               adr_i  : in std_logic_vector(11 downto 2);
+               wre_i  : in std_logic;
+               bsel_i : in std_logic_vector(3 downto 0);
+               dat_i  : in std_logic_vector(31 downto 0);
+               dat_o  : out std_logic_vector(31 downto 0);
+
+               -- Memory wiring for Master CPU
+               clk_m  : in std_logic;
+    en_m   : in std_logic;
+    we_m   : in std_logic_vector(3 downto 0);
+    addr_m : in std_logic_vector(9 downto 0);
+    din_m  : in std_logic_vector(31 downto 0);
+    dout_m : out std_logic_vector(31 downto 0)
+
+       );
+end lx_rocon_dmem;
+
+architecture rtl of lx_rocon_dmem is
+
+       signal wre_i_s : std_logic_vector(3 downto 0);
+
+begin
+
+       wre_i_s <= bsel_i when (wre_i = '1') else "0000";
+
+       I_RAMB: xilinx_dualport_bram
+       generic map
+       (
+               we_width => 4,
+               byte_width => 8,
+               address_width => 10
+       )
+       port map
+       (
+               -- Tumblr port
+               clka => clk_i,
+               rsta => '0',
+               ena => ce_i,
+               wea => wre_i_s,
+               addra => adr_i(11 downto 2),
+               dina => dat_i,
+               douta => dat_o,
+
+               -- Master CPU port
+               clkb => clk_m,
+               rstb => '0',
+               enb => en_m,
+               web => we_m,
+               addrb => addr_m,
+               dinb => din_m,
+               doutb => dout_m
+       );
+
+end rtl;
diff --git a/hw/lx-rocon_tumbl/lx_rocon_gprf_abd.vhd b/hw/lx-rocon_tumbl/lx_rocon_gprf_abd.vhd
new file mode 100644 (file)
index 0000000..3e825a6
--- /dev/null
@@ -0,0 +1,161 @@
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.mbl_Pkg.all;
+use work.lx_rocon_pkg.all;
+
+-- 32x32b General Puprose Registers for Tumbl Core
+-- Uses 3 BRAMs
+
+entity lx_rocon_gprf_abd is
+       port
+       (
+               clk_i        :  in std_logic;
+               rst_i        :  in std_logic;
+               clken_i      :  in std_logic;
+
+               ID2GPRF_i    :  in ID2GPRF_Type;
+               MEM_WRB_i    :  in WRB_Type;
+               GPRF2EX_o    :  out GPRF2EX_Type
+       );
+end entity lx_rocon_gprf_abd;
+
+architecture rtl of lx_rocon_gprf_abd is
+
+       signal  rdix_rA_s    : std_logic_vector(4 downto 0);
+       signal  rdix_rB_s    : std_logic_vector(4 downto 0);
+       signal  rdix_rD_s    : std_logic_vector(4 downto 0);
+
+       signal  wre_rD_s     : std_logic;
+       signal  ena_rA_s     : std_logic;
+       signal  ena_rB_s     : std_logic;
+       signal  ena_rD_s     : std_logic;
+
+       signal  clken_s      : std_logic;
+
+       signal  wthru_rA_r   : std_logic;
+       signal  rA_DOA_s     : std_logic_vector(31 downto 0);
+       signal  rA_DOB_s     : std_logic_vector(31 downto 0);
+       signal  wthru_rB_r   : std_logic;
+       signal  rB_DOA_s     : std_logic_vector(31 downto 0);
+       signal  rB_DOB_s     : std_logic_vector(31 downto 0);
+       signal  wthru_rD_r   : std_logic;
+       signal  rD_DOA_s     : std_logic_vector(31 downto 0);
+       signal  rD_DOB_s     : std_logic_vector(31 downto 0);
+
+begin
+
+       -- writeback if WRB_EX or WRB_MEM, but not when r0 involved
+       wre_rD_s <= '1' when ((MEM_WRB_i.wrb_Action /= NO_WRB) and
+                                                       (MEM_WRB_i.wrix_rD /= "00000")) else '0';
+
+       -- ports A should remain unchanged when clken_i is low, while also
+       -- reading from the same address as will be written to should be disabled
+       -- (setup for writeThru of data_rD)
+       ena_rA_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rA /= MEM_WRB_i.wrix_rD)) else '0';
+       ena_rB_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rB /= MEM_WRB_i.wrix_rD)) else '0';
+       ena_rD_s <= '1' when rst_i = '1' else clken_i when ((ID2GPRF_i.rdix_rD /= MEM_WRB_i.wrix_rD)) else '0';
+
+       -- make sure reset does it's job (writes 0 to R0 and resets the ports)
+       clken_s <= rst_i or clken_i;
+       rdix_rA_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rA;
+       rdix_rB_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rB;
+       rdix_rD_s <= (others => '0') when rst_i = '1' else ID2GPRF_i.rdix_rD;
+
+       GPRF2EX_o.data_rA <= rA_DOA_s when (wthru_rA_r = '0') else rA_DOB_s;
+       GPRF2EX_o.data_rB <= rB_DOA_s when (wthru_rB_r = '0') else rB_DOB_s;
+       GPRF2EX_o.data_rD <= rD_DOA_s when (wthru_rD_r = '0') else rD_DOB_s;    -- also for rD ???
+
+       I_rA: xilinx_dualport_bram
+       generic map
+       (
+               byte_width => 32,
+               we_width => 1,
+               address_width => 5
+       )
+       port map
+       (
+               clka => clk_i,
+               rsta => rst_i,
+               ena => ena_rA_s,
+               wea(0) => rst_i,
+               addra => rdix_rA_s,
+               dina => C_32_ZEROS,
+               douta => rA_DOA_s,
+               -- Write-back
+               clkb => clk_i,
+               rstb => rst_i,
+               enb => clken_s,
+               web(0) => wre_rD_s,
+               addrb => MEM_WRB_i.wrix_rD,
+               dinb => MEM_WRB_i.data_rD,
+               doutb => rA_DOB_s
+       );
+
+       I_rB: xilinx_dualport_bram
+       generic map
+       (
+               byte_width => 32,
+               we_width => 1,
+               address_width => 5
+       )
+       port map
+       (
+               clka => clk_i,
+               rsta => rst_i,
+               ena => ena_rB_s,
+               wea(0) => rst_i,
+               addra => rdix_rB_s,
+               dina => C_32_ZEROS,
+               douta => rB_DOA_s,
+               -- Write-back
+               clkb => clk_i,
+               rstb => rst_i,
+               enb => clken_s,
+               web(0) => wre_rD_s,
+               addrb => MEM_WRB_i.wrix_rD,
+               dinb => MEM_WRB_i.data_rD,
+               doutb => rB_DOB_s
+       );
+
+       I_rD: xilinx_dualport_bram
+       generic map
+       (
+               byte_width => 32,
+               we_width => 1,
+               address_width => 5
+       )
+       port map
+       (
+               clka => clk_i,
+               rsta => rst_i,
+               ena => ena_rD_s,
+               wea(0) => rst_i,
+               addra => rdix_rD_s,
+               dina => C_32_ZEROS,
+               douta => rD_DOA_s,
+               -- Write-back
+               clkb => clk_i,
+               rstb => rst_i,
+               enb => clken_s,
+               web(0) => wre_rD_s,
+               addrb => MEM_WRB_i.wrix_rD,
+               dinb => MEM_WRB_i.data_rD,
+               doutb => rD_DOB_s
+       );
+
+       p_regd: process(clk_i)
+       begin
+               if clk_i = '1' and clk_i'event then
+                       if (clken_i = '1') then
+                               wthru_rA_r <= not ena_rA_s;
+                               wthru_rB_r <= not ena_rB_s;
+                               wthru_rD_r <= not ena_rD_s;
+                       end if;
+               end if;
+       end process;
+
+end architecture rtl;
diff --git a/hw/lx-rocon_tumbl/lx_rocon_imem.vhd b/hw/lx-rocon_tumbl/lx_rocon_imem.vhd
new file mode 100644 (file)
index 0000000..fc61dc6
--- /dev/null
@@ -0,0 +1,64 @@
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.mbl_Pkg.all;
+use work.lx_rocon_pkg.all;
+
+-- 2 kB instruction memory for Thumbl core
+-- To be flashed from the Master CPU
+
+entity lx_rocon_imem is
+       port
+       (
+               -- Memory wiring for Tumbl
+               clk_i : in std_logic;
+               cs_i  : in std_logic;
+               adr_i : in std_logic_vector(10 downto 2);
+               dat_o : out std_logic_vector(31 downto 0);
+
+               -- Memory wiring for Master CPU
+               clk_m  : in std_logic;
+    en_m   : in std_logic;
+    we_m   : in std_logic_vector(3 downto 0);
+    addr_m : in std_logic_vector(8 downto 0);
+    din_m  : in std_logic_vector(31 downto 0);
+    dout_m : out std_logic_vector(31 downto 0)
+
+       );
+end lx_rocon_imem;
+
+architecture rtl of lx_rocon_imem is
+begin
+
+       I_RAMB: xilinx_dualport_bram
+       generic map
+       (
+               we_width => 4,
+               byte_width => 8,
+               address_width => 9
+       )
+       port map
+       (
+               -- Tumblr port
+               clka => clk_i,
+               rsta => '0',
+               ena => cs_i,
+               wea => "0000",
+               addra => adr_i(10 downto 2),
+               dina => C_32_ZEROS,
+               douta => dat_o,
+
+               -- Master CPU port
+               clkb => clk_m,
+               rstb => '0',
+               enb => en_m,
+               web => we_m,
+               addrb => addr_m,
+               dinb => din_m,
+               doutb => dout_m
+       );
+
+end rtl;
diff --git a/hw/lx-rocon_tumbl/lx_rocon_tumbl.vhd b/hw/lx-rocon_tumbl/lx_rocon_tumbl.vhd
new file mode 100644 (file)
index 0000000..0063c10
--- /dev/null
@@ -0,0 +1,298 @@
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.mbl_Pkg.all;
+use work.lx_rocon_pkg.all;
+
+-- Tumbl configured as a coprocessor for lx_rocon
+-- Uses 10 bits width address bus with HW barrel and multiplier
+
+entity lx_rocon_tumbl is
+       generic
+       (
+               IMEM_ABITS_g : positive := 11;
+               DMEM_ABITS_g : positive := 12;
+               --
+               USE_HW_MUL_g :  boolean := true;
+               USE_BARREL_g :  boolean := true
+       );
+       port
+       (
+               clk_i        :  in std_logic;
+               rst_i        :  in std_logic;
+         halt_i       :  in std_logic;
+               int_i        :  in std_logic;
+               trace_i      :  in std_logic;
+               trace_kick_i :  in std_logic;
+
+               -- Program counter
+               pc_o         : out std_logic_vector(31 downto 0);
+
+               -- Internal memory (instruction)
+               imem_clk  : in std_logic;
+    imem_en   : in std_logic;
+    imem_we   : in std_logic_vector(3 downto 0);
+    imem_addr : in std_logic_vector(8 downto 0);
+    imem_din  : in std_logic_vector(31 downto 0);
+    imem_dout : out std_logic_vector(31 downto 0);
+
+               -- Internal memory (data)
+               dmem_clk  : in std_logic;
+    dmem_en   : in std_logic;
+    dmem_we   : in std_logic_vector(3 downto 0);
+    dmem_addr : in std_logic_vector(9 downto 0);
+    dmem_din  : in std_logic_vector(31 downto 0);
+    dmem_dout : out std_logic_vector(31 downto 0);
+
+               -- External memory bus
+               XMEMB_sel_o :  out std_logic;
+               XMEMB_i     :  in DMEMB2CORE_Type;
+               XMEMB_o     :  out CORE2DMEMB_Type;
+               --
+               bad_op_o    :  out std_logic;
+               done_o      :  out std_logic
+       );
+end entity lx_rocon_tumbl;
+
+architecture rtl of lx_rocon_tumbl is
+
+       constant DMEM_TEST_c : std_logic_vector((31-DMEM_ABITS_g) downto 0) := (others => '0');
+
+       signal imem_clken_s  : std_logic;
+       signal imem_addr_s   : std_logic_vector(31 downto 0);
+       signal imem_data_s   : std_logic_vector(31 downto 0);
+       signal gprf_clken_s  : std_logic;
+       signal core_clk_en_s : std_logic;
+       signal pc_ctrl_s     : std_logic;
+       signal c2dmemb_s     : CORE2DMEMB_Type;
+       signal dmem_data_s   : std_logic_vector(31 downto 0);
+       signal DMEMB_i_s     : DMEMB2CORE_Type;
+
+       signal MEM2CTRL_s    : MEM2CTRL_Type;
+       signal INT_CTRL_s    : INT_CTRL_Type;
+       signal ID2CTRL_s     : ID2CTRL_Type;
+
+       signal IF2ID_s,      IF2ID_r      : IF2ID_Type;
+       signal ID2EX_s,      ID2EX_r      : ID2EX_Type;
+       signal ID2GPRF_s                  : ID2GPRF_Type;
+       signal GPRF2EX_s                  : GPRF2EX_Type;
+       signal EX2IF_s,      EX2IF_r      : EX2IF_Type;
+       signal EX2MEM_s,     EX2MEM_r     : EX2MEM_Type;
+       signal EX_WRB_s,     EX_WRB_r     : WRB_Type;
+       signal MEM_WRB_s                  : WRB_Type;
+       signal IMM_LOCK_s,   IMM_LOCK_r   : IMM_LOCK_Type;
+       signal HAZARD_WRB_s, HAZARD_WRB_r : HAZARD_WRB_Type;
+       signal EX2MSR_s                   : MSR_Type;
+       signal MSR2EX_s                   : MSR_Type;
+       signal MEM_REG_s,    MEM_REG_r    : MEM_REG_Type;
+       signal dmem_sel_s,   dmem_sel_r   : std_logic;
+       signal BAD_OP_s                   : std_logic;
+       signal BAD_OP_up_s                : std_logic;
+       signal halt_s                     : std_logic;
+
+       signal imem_really_clken_s        : std_logic;
+       signal dmem_really_sel_s          : std_logic;
+       signal gprf_really_clken_s        : std_logic;
+
+begin
+
+       -- select internal data memory when all address bits above DMEM_ABITS_g are zero
+       dmem_sel_s  <= '1' when (c2dmemb_s.addr(31 downto DMEM_ABITS_g) = DMEM_TEST_c)
+                                                                       else '0';
+       XMEMB_sel_o <= not dmem_sel_s;
+       XMEMB_o     <= c2dmemb_s;
+       pc_o        <= ID2EX_r.program_counter; -- Program counter for EXEQ
+       bad_op_o    <= BAD_OP_s;
+       halt_s      <= halt_i or BAD_OP_up_s;
+
+       imem_really_clken_s <= imem_clken_s and core_clk_en_s;
+       dmem_really_sel_s   <= dmem_sel_s and core_clk_en_s;
+       gprf_really_clken_s <= gprf_clken_s and core_clk_en_s;
+
+       I_IMEM: lx_rocon_imem
+       port map
+       (
+               clk_i => clk_i,
+               cs_i  => imem_really_clken_s,
+               adr_i => imem_addr_s((IMEM_ABITS_g-1) downto 2),
+               dat_o => imem_data_s,
+
+               clk_m => imem_clk,
+               en_m => imem_en,
+               we_m => imem_we,
+               addr_m => imem_addr,
+               din_m => imem_din,
+               dout_m => imem_dout
+       );
+
+       I_DMEM: lx_rocon_dmem
+       port map
+       (
+               clk_i  => clk_i,
+               ce_i   => dmem_really_sel_s,
+               adr_i  => c2dmemb_s.addr((DMEM_ABITS_g-1) downto 2),
+               wre_i  => c2dmemb_s.wre,
+               bsel_i => c2dmemb_s.bSel,
+               dat_i  => c2dmemb_s.data,
+               dat_o  => dmem_data_s,
+
+               clk_m => dmem_clk,
+               en_m => dmem_en,
+               we_m => dmem_we,
+               addr_m => dmem_addr,
+               din_m => dmem_din,
+               dout_m => dmem_dout
+       );
+
+       I_FETCH: fetch
+       port map
+       (
+               prog_cntr_i => IF2ID_r.program_counter,
+               inc_pc_i    => pc_ctrl_s,
+               EX2IF_i     => EX2IF_r,
+               IF2ID_o     => IF2ID_s
+       );
+
+       I_DECODE: decode
+       generic map(USE_HW_MUL_g, USE_BARREL_g)
+       port map
+       (
+               IF2ID_i     => IF2ID_r,
+               imem_data_i => imem_data_s,
+               --
+               ID2GPRF_o   => ID2GPRF_s,
+               ID2EX_o     => ID2EX_s,
+               --
+               INT_CTRL_i  => INT_CTRL_s,
+               ID2CTRL_o   => ID2CTRL_s,
+               --
+               noLiteOpc_o => BAD_OP_s
+       );
+
+       I_GPRF: lx_rocon_gprf_abd
+       port map
+       (
+               clk_i        => clk_i,
+               rst_i        => rst_i,
+               clken_i      => gprf_really_clken_s,
+               --
+               ID2GPRF_i    => ID2GPRF_s,
+               MEM_WRB_i    => MEM_WRB_s,
+               GPRF2EX_o    => GPRF2EX_s
+       );
+
+       I_EXEQ: exeq
+       generic map(USE_HW_MUL_g, USE_BARREL_g)
+       port map
+       (
+               ID2EX_i      => ID2EX_r,
+               GPRF2EX_i    => GPRF2EX_s,
+               EX2IF_o      => EX2IF_s,
+               --
+               EX_WRB_i     => EX_WRB_r,
+               EX_WRB_o     => EX_WRB_s,
+               MEM_WRB_i    => MEM_WRB_s,
+               --
+               HAZARD_WRB_i => HAZARD_WRB_r,
+               HAZARD_WRB_o => HAZARD_WRB_s,
+               --
+               IMM_LOCK_i   => IMM_LOCK_r,
+               IMM_LOCK_o   => IMM_LOCK_s,
+               --
+               MSR_i        => MSR2EX_s,
+               MSR_o        => EX2MSR_s,
+               --
+               EX2MEM_o     => EX2MEM_s
+       );
+
+       -- this is a very simple address block decoder, just "internal" dmem or "external"
+       -- clken and int hardwired for fast internal data-memory
+       DMEMB_i_s.clken <= '1'          when (dmem_sel_s = '1') else XMEMB_i.clken;
+       DMEMB_i_s.data  <=  dmem_data_s when (dmem_sel_r = '1') else XMEMB_i.data;
+       DMEMB_i_s.int   <= XMEMB_i.int;
+
+       I_MEM: mem
+       port map
+       (
+               EX2MEM_i    => EX2MEM_r,
+               MEM_WRB_o   => MEM_WRB_s,
+               --
+               DMEMB_i     => DMEMB_i_s,
+               DMEMB_o     => c2dmemb_s,
+               --
+               MEM_REG_i  => MEM_REG_r,
+               MEM_REG_o  => MEM_REG_s,
+               --
+               MEM2CTRL_o => MEM2CTRL_s
+       );
+
+       I_CTRL: core_ctrl
+       port map
+       (
+               clk_i           => clk_i,
+               rst_i           => rst_i,
+         halt_i          => halt_s,
+               int_i           => int_i,
+               trace_i         => trace_i,
+               trace_kick_i    => trace_kick_i,
+               core_clk_en_o   => core_clk_en_s,
+               -- specific fetch i/o
+               imem_addr_o     => imem_addr_s,
+               imem_clken_o    => imem_clken_s,
+               pc_ctrl_o       => pc_ctrl_s,
+               -- fetch to decode pipeline registers
+               IF2ID_REG_i     => IF2ID_s,
+               IF2ID_REG_o     => IF2ID_r,
+               -- decode to exeq pipeline registers
+               ID2EX_REG_i     => ID2EX_s,
+               ID2EX_REG_o     => ID2EX_r,
+               -- GPRF control
+               gprf_clken_o    => gprf_clken_s,
+               -- exeq to fetch feedback registers
+               EX2IF_REG_i     => EX2IF_s,
+               EX2IF_REG_o     => EX2IF_r,
+               -- exeq to mem pipeline registers
+               EX2MEM_REG_i    => EX2MEM_s,
+               EX2MEM_REG_o    => EX2MEM_r,
+               -- mem pipeline register
+               MEM_REG_i       => MEM_REG_s,
+               MEM_REG_o       => MEM_REG_r,
+               -- decode control i/o
+               ID2CTRL_i       => ID2CTRL_s,
+               INT_CTRL_o      => INT_CTRL_s,
+               -- exeq control i/o
+               EX_WRB_i        => EX_WRB_s,
+               EX_WRB_o        => EX_WRB_r,
+               -- data hazard i/o
+               HAZARD_WRB_i    => HAZARD_WRB_s,
+               HAZARD_WRB_o    => HAZARD_WRB_r,
+               -- for handling the 'IMM' instruction
+               IMM_LOCK_i      => IMM_LOCK_s,
+               IMM_LOCK_o      => IMM_LOCK_r,
+               -- for handling the Machine Status Register
+               MSR_i           => EX2MSR_s,
+               MSR_o           => MSR2EX_s,
+               -- miscellaneous
+               MEM2CTRL_i      => MEM2CTRL_s,
+               done_o          => done_o
+       );
+
+       regd_proc: process(clk_i, rst_i)
+       begin
+               if clk_i = '1' and clk_i'event then
+                       if (rst_i = '1') then           -- synchronous reset ...
+                               dmem_sel_r <= '1';
+                               BAD_OP_up_s <= '0';
+                       else                            -- delay select_external_mem (needed for reading ...)
+                               if (DMEMB_i_s.clken = '1') then
+                                       dmem_sel_r <= dmem_sel_s;   -- OR c2dmemb_s.wre; ??
+                               end if;
+                               BAD_OP_up_s <= BAD_OP_up_s or BAD_OP_s;
+                       end if;
+               end if;
+       end process regd_proc;
+
+end architecture rtl;
diff --git a/hw/lx-rocon_tumbl/tb/lx_rocon_tumbl_tb.vhd b/hw/lx-rocon_tumbl/tb/lx_rocon_tumbl_tb.vhd
new file mode 100644 (file)
index 0000000..b25f986
--- /dev/null
@@ -0,0 +1,143 @@
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+USE ieee.numeric_std.ALL;
+USE work.mbl_Pkg.ALL;
+USE work.lx_rocon_pkg.ALL;
+
+-- Tumbl core testbench
+
+ENTITY lx_rocon_tumbl_tb IS
+END lx_rocon_tumbl_tb;
+
+ARCHITECTURE behavior OF lx_rocon_tumbl_tb IS
+
+    -- Component Declaration for the Unit Under Test (UUT)
+
+    COMPONENT lx_rocon_tumbl
+    PORT(
+         clk_i : IN  std_logic;
+         rst_i : IN  std_logic;
+         halt_i : IN  std_logic;
+         int_i : IN  std_logic;
+         trace_i :  IN std_logic;
+         trace_kick_i :  IN std_logic;
+         pc_o  : OUT  std_logic_vector(31 downto 0);
+         imem_clk : IN  std_logic;
+         imem_en : IN  std_logic;
+         imem_we : IN  std_logic_vector(3 downto 0);
+         imem_addr : IN  std_logic_vector(8 downto 0);
+         imem_din : IN  std_logic_vector(31 downto 0);
+         imem_dout : OUT  std_logic_vector(31 downto 0);
+         dmem_clk : IN  std_logic;
+         dmem_en : IN  std_logic;
+         dmem_we : IN  std_logic_vector(3 downto 0);
+         dmem_addr : IN  std_logic_vector(9 downto 0);
+         dmem_din : IN  std_logic_vector(31 downto 0);
+         dmem_dout : OUT  std_logic_vector(31 downto 0);
+         XMEMB_sel_o : OUT  std_logic;
+         XMEMB_i :  IN  DMEMB2CORE_Type;
+                    XMEMB_o :  OUT  CORE2DMEMB_Type;
+         bad_op_o : OUT  std_logic;
+         done_o : OUT  std_logic
+        );
+    END COMPONENT;
+
+
+   --Inputs
+   signal clk_i : std_logic := '0';
+   signal rst_i : std_logic := '0';
+   signal halt_i : std_logic := '0';
+   signal int_i : std_logic := '0';
+        signal trace_i : std_logic := '0';
+        signal trace_kick_i : std_logic := '0';
+   signal imem_clk : std_logic := '0';
+   signal imem_en : std_logic := '0';
+   signal imem_we : std_logic_vector(3 downto 0) := (others => '0');
+   signal imem_addr : std_logic_vector(8 downto 0) := (others => '0');
+   signal imem_din : std_logic_vector(31 downto 0) := (others => '0');
+   signal dmem_clk : std_logic := '0';
+   signal dmem_en : std_logic := '0';
+   signal dmem_we : std_logic_vector(3 downto 0) := (others => '0');
+   signal dmem_addr : std_logic_vector(9 downto 0) := (others => '0');
+   signal dmem_din : std_logic_vector(31 downto 0) := (others => '0');
+   signal XMEMB_i : DMEMB2CORE_Type := (clken => '0', data => (others => '0'), int => '0');
+
+        --Outputs
+        signal pc_o : std_logic_vector(31 downto 0);
+   signal imem_dout : std_logic_vector(31 downto 0);
+   signal dmem_dout : std_logic_vector(31 downto 0);
+   signal XMEMB_sel_o : std_logic;
+   signal XMEMB_o : CORE2DMEMB_Type;
+   signal bad_op_o : std_logic;
+   signal done_o : std_logic;
+
+   -- Clock period definitions
+   constant clk_i_period : time := 20 ns; -- 50 MHz
+   constant imem_clk_period : time := 13.8 ns; -- 72 MHz
+   constant dmem_clk_period : time := 13.8 ns; -- 72 MHz
+
+BEGIN
+
+       -- Instantiate the Unit Under Test (UUT)
+   uut: lx_rocon_tumbl PORT MAP (
+          clk_i => clk_i,
+          rst_i => rst_i,
+          halt_i => halt_i,
+          int_i => int_i,
+                                       trace_i => trace_i,
+                                       trace_kick_i => trace_kick_i,
+                                       pc_o => pc_o,
+          imem_clk => imem_clk,
+          imem_en => imem_en,
+          imem_we => imem_we,
+          imem_addr => imem_addr,
+          imem_din => imem_din,
+          imem_dout => imem_dout,
+          dmem_clk => dmem_clk,
+          dmem_en => dmem_en,
+          dmem_we => dmem_we,
+          dmem_addr => dmem_addr,
+          dmem_din => dmem_din,
+          dmem_dout => dmem_dout,
+          XMEMB_sel_o => XMEMB_sel_o,
+          XMEMB_i => XMEMB_i,
+          XMEMB_o => XMEMB_o,
+          bad_op_o => bad_op_o,
+          done_o => done_o
+        );
+
+   -- Clock process definitions
+   clk_i_process :process
+   begin
+               clk_i <= '0';
+               wait for clk_i_period/2;
+               clk_i <= '1';
+               wait for clk_i_period/2;
+   end process;
+
+   imem_clk_process :process
+   begin
+               imem_clk <= '0';
+               wait for imem_clk_period/2;
+               imem_clk <= '1';
+               wait for imem_clk_period/2;
+   end process;
+
+   dmem_clk_process :process
+   begin
+               dmem_clk <= '0';
+               wait for dmem_clk_period/2;
+               dmem_clk <= '1';
+               wait for dmem_clk_period/2;
+   end process;
+
+
+   -- Stimulus process
+   stim_proc: process
+   begin
+      -- External ModelSim script
+
+      wait;
+   end process;
+
+END;
diff --git a/hw/lx_rocon_pkg.vhd b/hw/lx_rocon_pkg.vhd
new file mode 100644 (file)
index 0000000..410bef2
--- /dev/null
@@ -0,0 +1,334 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+use ieee.std_logic_unsigned.all;
+use ieee.numeric_std.all;
+use work.mbl_Pkg.all;
+
+-- Entities within lx_rocon
+
+package lx_rocon_pkg is
+
+       -- IRC register
+       component irc_register
+       port
+       (
+               clk      : in std_logic;
+               reset    : in std_logic;
+               a0, b0   : in std_logic;
+               index0   : in std_logic;
+               mark0    : in std_logic;
+               data_in  : in std_logic;
+               data_out : out std_logic_vector(31 downto 0);
+               ce       : in std_logic_vector(1 downto 0);
+               rd       : in std_logic;
+               ta       : out std_logic;
+               wr       : in std_logic
+       );
+       end component;
+
+       -- BCD counter
+       component bcd
+       generic
+       (
+               width      : integer
+       );
+       port
+       (
+               reset      : in std_logic;
+               en         : in std_logic;
+               clk        : in std_logic;
+               value      : out std_logic_vector((width-1) downto 0)
+       );
+       end component;
+
+       -- Quadcount
+       component qcounter
+       port
+       (
+               clk          : in std_logic;
+               reset        : in std_logic;
+               a0, b0       : in std_logic;
+               index0       : in std_logic;
+
+               a_rise       : out std_logic;
+               a_fall       : out std_logic;
+               b_rise       : out std_logic;
+               b_fall       : out std_logic;
+
+               qcount       : out std_logic_vector (31 downto 0);
+               qcount_index : out std_logic_vector (31 downto 0);
+               ab_event     : out std_logic;
+               ab_error     : out std_logic
+       );
+       end component;
+
+       -- D sampler
+       component dff
+       port
+       (
+               clk   : in std_logic;
+               reset : in std_logic;
+               d     : in std_logic;
+               q     : out std_logic
+       );
+  end component;
+
+       -- D sampler (filtered)
+       component dff2
+       port
+       (
+               clk   : in std_logic;
+               reset : in std_logic;
+               d     : in std_logic;
+               q     : out std_logic
+       );
+  end component;
+
+       --------------------------------------------------------------------------------
+       -- TUMBL
+       --------------------------------------------------------------------------------
+
+       component lx_rocon_tumbl
+       generic
+       (
+               IMEM_ABITS_g : positive := 12;
+               DMEM_ABITS_g : positive := 12;
+               --
+               USE_HW_MUL_g :  boolean := true;
+               USE_BARREL_g :  boolean := true
+       );
+       port
+       (
+               clk_i        :  in std_logic;
+               rst_i        :  in std_logic;
+         halt_i       :  in std_logic;
+               int_i        :  in std_logic;
+               trace_i      :  in std_logic;
+               trace_kick_i :  in std_logic;
+               pc_o         :  out std_logic_vector(31 downto 0);
+               imem_clk  : in std_logic;
+    imem_en   : in std_logic;
+    imem_we   : in std_logic_vector(3 downto 0);
+    imem_addr : in std_logic_vector(8 downto 0);
+    imem_din  : in std_logic_vector(31 downto 0);
+    imem_dout : out std_logic_vector(31 downto 0);
+               dmem_clk  : in std_logic;
+    dmem_en   : in std_logic;
+    dmem_we   : in std_logic_vector(3 downto 0);
+    dmem_addr : in std_logic_vector(9 downto 0);
+    dmem_din  : in std_logic_vector(31 downto 0);
+    dmem_dout : out std_logic_vector(31 downto 0);
+               XMEMB_sel_o :  out std_logic;
+               XMEMB_i     :  in DMEMB2CORE_Type;
+               XMEMB_o     :  out CORE2DMEMB_Type;
+               bad_op_o    :  out std_logic;
+               done_o      :  out std_logic
+       );
+       end component;
+
+       component lx_rocon_imem
+       port
+       (
+               clk_i : in std_logic;
+               cs_i  : in std_logic;
+               adr_i : in std_logic_vector(10 downto 2);
+               dat_o : out std_logic_vector(31 downto 0);
+               clk_m  : in std_logic;
+    en_m   : in std_logic;
+    we_m   : in std_logic_vector(3 downto 0);
+    addr_m : in std_logic_vector(8 downto 0);
+    din_m  : in std_logic_vector(31 downto 0);
+    dout_m : out std_logic_vector(31 downto 0)
+
+       );
+       end component;
+
+       component lx_rocon_dmem
+       port
+       (
+               clk_i  : in std_logic;
+               ce_i   : in std_logic;
+               adr_i  : in std_logic_vector(11 downto 2);
+               wre_i  : in std_logic;
+               bsel_i : in std_logic_vector(3 downto 0);
+               dat_i  : in std_logic_vector(31 downto 0);
+               dat_o  : out std_logic_vector(31 downto 0);
+               clk_m  : in std_logic;
+    en_m   : in std_logic;
+    we_m   : in std_logic_vector(3 downto 0);
+    addr_m : in std_logic_vector(9 downto 0);
+    din_m  : in std_logic_vector(31 downto 0);
+    dout_m : out std_logic_vector(31 downto 0)
+       );
+       end component;
+
+       component lx_rocon_gprf_abd
+       port
+       (
+               clk_i        :  in std_logic;
+               rst_i        :  in std_logic;
+               clken_i      :  in std_logic;
+               ID2GPRF_i    :  in ID2GPRF_Type;
+               MEM_WRB_i    :  in WRB_Type;
+               GPRF2EX_o    :  out GPRF2EX_Type
+       );
+       end component;
+
+       --------------------------------------------------------------------------------
+       -- MEMORY BUS
+       --------------------------------------------------------------------------------
+
+       -- Calibration read register
+       component calibration_read_register
+       generic
+       (
+               id          : std_logic_vector(31 downto 0)
+       );
+       port
+       (
+               data_out    : out std_logic_vector(31 downto 0);
+               rd          : in std_logic;
+               ta          : out std_logic
+       );
+       end component;
+
+       -- Calibration write register
+       component calibration_write_register
+       port
+       (
+               clk         : in std_logic;
+               reset       : in std_logic;
+               ce          : in std_logic;
+               data_in     : in std_logic_vector(31 downto 0);
+               data_out    : out std_logic_vector(31 downto 0);
+               rd          : in std_logic;
+               bls         : in std_logic_vector(3 downto 0);
+               ta          : out std_logic
+       );
+       end component;
+
+       -- Calibration interconnect
+       component bus_calibration
+       port
+       (
+               clk         : in std_logic;
+               reset       : in std_logic;
+               ce          : in std_logic;
+               address     : in std_logic_vector(1 downto 0);
+               data_in     : in std_logic_vector(31 downto 0);
+               data_out    : out std_logic_vector(31 downto 0);
+               rd          : in std_logic;
+               bls         : in std_logic_vector(3 downto 0);
+               ta          : out std_logic
+       );
+       end component;
+
+       -- IRC interconnect
+       component bus_irc
+       port
+       (
+               clk         : in std_logic;
+               reset       : in std_logic;
+
+               address     : in std_logic_vector(3 downto 0);
+               ce          : in std_logic;
+
+               data_in     : in std_logic;
+               data_out    : out std_logic_vector(31 downto 0);
+
+               rd          : in std_logic;
+               wr          : in std_logic;
+               ta          : out std_logic;
+
+               irc1_a      : in std_logic;
+               irc1_b      : in std_logic;
+               irc1_index  : in std_logic;
+               irc1_mark   : in std_logic;
+
+               irc2_a      : in std_logic;
+               irc2_b      : in std_logic;
+               irc2_index  : in std_logic;
+               irc2_mark   : in std_logic;
+
+               irc3_a      : in std_logic;
+               irc3_b      : in std_logic;
+               irc3_index  : in std_logic;
+               irc3_mark   : in std_logic;
+
+               irc4_a      : in std_logic;
+               irc4_b      : in std_logic;
+               irc4_index  : in std_logic;
+               irc4_mark   : in std_logic
+       );
+       end component;
+
+       -- BCD interconnect
+       component bus_bcd
+       port
+       (
+               reset      : in std_logic;
+               en         : in std_logic;
+               clk        : in std_logic;
+               data_out   : out std_logic_vector(31 downto 0);
+               rd         : in std_logic;
+               ta         : out std_logic
+       );
+       end component;
+
+       -- Tumbl interconnect
+       component bus_tumbl
+       port
+       (
+               clk_100m : in std_logic;
+               clk_50m  : in std_logic;
+               ce       : in std_logic;
+               reset    : in std_logic;
+    rd       : in std_logic;
+    bls      : in std_logic_vector(3 downto 0);
+    address  : in std_logic_vector(11 downto 0);
+    data_in  : in std_logic_vector(31 downto 0);
+    data_out : out std_logic_vector(31 downto 0);
+               ta       : out std_logic;
+               XMEMB_sel_o :  out std_logic;
+               XMEMB_i     :  in DMEMB2CORE_Type;
+               XMEMB_o     :  out CORE2DMEMB_Type
+  );
+       end component;
+
+       --------------------------------------------------------------------------------
+       -- BRAM
+       --------------------------------------------------------------------------------
+
+       component xilinx_dualport_bram
+       generic
+       (
+               byte_width : positive := 8;
+               address_width : positive := 8;
+               we_width : positive := 4
+       );
+       port
+       (
+               clka : in std_logic;
+               rsta : in std_logic;
+               ena : in std_logic;
+               wea : in std_logic_vector((we_width-1) downto 0);
+               addra : in std_logic_vector((address_width-1) downto 0);
+               dina : in std_logic_vector(((byte_width*we_width)-1) downto 0);
+               douta : out std_logic_vector(((byte_width*we_width)-1) downto 0);
+               clkb : in std_logic;
+               rstb : in std_logic;
+               enb : in std_logic;
+               web : in std_logic_vector((we_width-1) downto 0);
+               addrb : in std_logic_vector((address_width-1) downto 0);
+               dinb : in std_logic_vector(((byte_width*we_width)-1) downto 0);
+               doutb : out std_logic_vector(((byte_width*we_width)-1) downto 0)
+       );
+       end component;
+
+end lx_rocon_pkg;
+
+package body lx_rocon_pkg is
+
+
+end lx_rocon_pkg;
index 36d48304b9095dc1c9ce511458cd1c128b068c99..cdfca3d8c582ab3e0fe55a7dc9fd1c36afda02c1 100644 (file)
@@ -1,13 +1,22 @@
-vhdl work "dff.vhd"
+vhdl work "tumbl/mbl_Pkg.vhd"
+vhdl work "lx_rocon_pkg.vhd"
+vhdl work "dff2.vhd"
+vhdl work "xilinx_dualport_bram.vhd"
 vhdl work "qcounter.vhd"
+vhdl work "tumbl/mem.vhd"
+vhdl work "tumbl/fetch.vhd"
+vhdl work "tumbl/exeq.vhd"
+vhdl work "tumbl/decode.vhd"
+vhdl work "tumbl/core_ctrl.vhd"
+vhdl work "lx-rocon_tumbl/lx_rocon_imem.vhd"
+vhdl work "lx-rocon_tumbl/lx_rocon_gprf_abd.vhd"
+vhdl work "lx-rocon_tumbl/lx_rocon_dmem.vhd"
 vhdl work "irc_reader.vhd"
+vhdl work "lx-rocon_tumbl/lx_rocon_tumbl.vhd"
 vhdl work "irc_register.vhd"
-vhdl work "ipcore_dir/control_bram.vhd"
 vhdl work "calibration_write_register.vhd"
 vhdl work "calibration_read_register.vhd"
-vhdl work "bcd.vhd"
+vhdl work "bus_tumbl.vhd"
 vhdl work "bus_irc.vhd"
-vhdl work "bus_control_bram.vhd"
 vhdl work "bus_calibration.vhd"
-vhdl work "bus_bcd.vhd"
 vhdl work "lx_rocon_top.vhd"
index a98a0b80242dd330f9400f303fc3ba2ca3ad5321..44a8d96668fa69c001338765d52015516bd199c5 100644 (file)
@@ -4,13 +4,19 @@ use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
 
--- lx_rocon_top - wires the modules with outside world
+library unisim;
+use unisim.vcomponents.all;
+
+use work.mbl_Pkg.all;
+use work.lx_rocon_pkg.all;
+
+-- lx_rocon_top - wires the modules with the outside world
 
 -- ======================================================
---  INTERNAL MEMORY BUS
+--  MASTER CPU EXTERNAL MEMORY BUS
 -- ======================================================
 --
--- Internal memory bus has the following wires:
+-- Master cpu memory bus has the following wires:
 --
 -- - address[15..0]          The address
 -- - data_in[31..0]          The data coming to bus
@@ -19,12 +25,17 @@ use ieee.numeric_std.all;
 -- - bls[3..0]               Write enable for respective bytes, active LOW
 --                           In some cases, only WR is used
 -- - ta                      Transaction acknowledge (latches data out), active LOW, multiplexed
+--
+-- ======================================================
+--  TUMBL EXTERNAL MEMORY BUS
+-- ======================================================
 
 entity lx_rocon_top is
        port
        (
                -- External
-               clk_cpu   : in std_logic;
+               --clk_cpu   : in std_logic;
+               clk_50m   : in std_logic;
 
                cs0_xc   : in std_logic;
 
@@ -61,20 +72,22 @@ architecture Behavioral of lx_rocon_top is
 
        -- Reset signal
        signal reset : std_logic;
+       signal neg_init : std_logic;
+
+       -- 100 MHz clock
+       signal clk_100m : std_logic;
+       signal clk_100m_fb : std_logic;
+       signal clk_100m_locked : std_logic;
 
        -- Peripherals on the memory bus
-       signal bram_out : std_logic_vector(31 downto 0);
-       signal bram_ta : std_logic;
-       signal bram_ce : std_logic;
+       signal tumbl_out : std_logic_vector(31 downto 0);
+       signal tumbl_ta : std_logic;
+       signal tumbl_ce : std_logic;
 
        signal irc_reg_out : std_logic_vector(31 downto 0);
        signal irc_reg_ta : std_logic;
        signal irc_reg_ce : std_logic;
 
-       signal bcd_out : std_logic_vector(31 downto 0);
-       signal bcd_ta : std_logic;
-       signal bcd_ce : std_logic;
-
        signal calib_out : std_logic_vector(31 downto 0);
        signal calib_ta : std_logic;
        signal calib_ce : std_logic;
@@ -96,115 +109,80 @@ architecture Behavioral of lx_rocon_top is
        -- Data latching is synchronous - it's purpose is to
        -- provide stable data for CPU on the bus on high rise
        -- of trans. ack signal
+       signal rd_f : std_logic;
+       signal rd_d : std_logic;
+
+       signal data_read : std_logic_vector(31 downto 0);
+
        signal i_ta : std_logic;
        signal i_rd : std_logic;
-       signal data_read : std_logic_vector(31 downto 0);
        signal acked : std_logic;
 
        -- Writing logic:
-       signal i_bls : std_logic_vector(3 downto 0);
+       signal bls_f : std_logic_vector(3 downto 0);
+       signal bls_d : std_logic_vector(3 downto 0);
+
        signal data_write : std_logic_vector(31 downto 0);
 
-       component bus_irc
-       port
-       (
-               clk         : in std_logic;
-               reset       : in std_logic;
-
-               address     : in std_logic_vector(3 downto 0);
-               ce          : in std_logic;
-
-               data_in     : in std_logic;
-               data_out    : out std_logic_vector(31 downto 0);
-
-               rd          : in std_logic;
-               wr          : in std_logic;
-               ta          : out std_logic;
-
-               irc1_a      : in std_logic;
-               irc1_b      : in std_logic;
-               irc1_index  : in std_logic;
-               irc1_mark   : in std_logic;
-
-               irc2_a      : in std_logic;
-               irc2_b      : in std_logic;
-               irc2_index  : in std_logic;
-               irc2_mark   : in std_logic;
-
-               irc3_a      : in std_logic;
-               irc3_b      : in std_logic;
-               irc3_index  : in std_logic;
-               irc3_mark   : in std_logic;
-
-               irc4_a      : in std_logic;
-               irc4_b      : in std_logic;
-               irc4_index  : in std_logic;
-               irc4_mark   : in std_logic
-       );
-       end component;
+       signal i_bls : std_logic_vector(3 downto 0);
 
-       component bus_control_bram
-       port
-       (
-               clk : in std_logic;
-
-    ena : in std_logic;
-    wea : in std_logic_vector(3 downto 0);
-    addra : in std_logic_vector(8 downto 0);
-    dina : in std_logic_vector(31 downto 0);
-    douta : out std_logic_vector(31 downto 0);
-               taa : out std_logic;
-
-    enb : in std_logic;
-    web : in std_logic_vector(3 downto 0);
-    addrb : in std_logic_vector(8 downto 0);
-    dinb : in std_logic_vector(31 downto 0);
-    doutb : out std_logic_vector(31 downto 0)
-  );
-       end component;
-
-       component bus_bcd
-       port
-       (
-               reset      : in std_logic;
-               en         : in std_logic;
-               clk        : in std_logic;
-               ce         : in std_logic;
-               data_out   : out std_logic_vector(31 downto 0);
-               rd         : in std_logic;
-               ta         : out std_logic
-       );
-       end component;
+begin
 
-       component bus_calibration
-       port
+       -- Clocking
+       clk_100m_dcm_sp : DCM_SP
+       generic map
        (
-               clk         : in std_logic;
-               reset       : in std_logic;
-               ce          : in std_logic;
-               address     : in std_logic_vector(1 downto 0);
-               data_in     : in std_logic_vector(31 downto 0);
-               data_out    : out std_logic_vector(31 downto 0);
-               rd          : in std_logic;
-               bls         : in std_logic_vector(3 downto 0);
-               ta          : out std_logic
+               clkdv_divide => 2.0,
+               clkfx_divide => 1,
+               clkfx_multiply => 2,
+               clkin_divide_by_2 => false,
+               clkin_period => 20.0, -- 50 MHz
+               clkout_phase_shift => "NONE",
+               clk_feedback => "1X",
+               deskew_adjust => "SYSTEM_SYNCHRONOUS",
+               dfs_frequency_mode => "LOW",
+               dll_frequency_mode => "LOW",
+               dss_mode => "NONE",
+               duty_cycle_correction => true,
+               factory_jf => X"c080",
+               phase_shift => 0,
+               startup_wait => false
+       )
+       port map
+       (
+               clk0 => clk_100m_fb,
+               clk180 => open,
+               clk270 => open,
+               clk2x => clk_100m,
+               clk2x180 => open,
+               clk90 => open,
+               clkdv => open,
+               clkfx => open,
+               clkfx180 => open,
+               locked => clk_100m_locked,
+               psdone => open,
+               status => open,
+               clkfb => clk_100m_fb,
+               clkin => clk_50m,
+               dssen => '0',
+               psclk => '0',
+               psen => '0',
+               psincdec => '0',
+               rst => neg_init
        );
-       end component;
-
-begin
 
        -- IRC interconnect
        memory_bus_irc: bus_irc
        port map
        (
-               clk => clk_cpu,
+               clk => clk_100m,
                reset => reset,
                address => address(3 downto 0),
                ce => irc_reg_ce,
                data_in => data_in_bus(0),
                data_out => irc_reg_out,
                rd => i_rd,
-               wr => bls(0),
+               wr => i_bls(0),
                ta => irc_reg_ta,
 
                irc1_a => irc1_a,
@@ -228,43 +206,33 @@ begin
                irc4_mark => irc4_mark
        );
 
-       -- Control BRAM interconnect (9 kib)
-       memory_bus_control_bram: bus_control_bram
+       -- Tumbl coprocessor
+       memory_bus_tumbl: bus_tumbl
        port map
        (
-               clk => clk_cpu,
-               ena => bram_ce,
-               taa => bram_ta,
-               wea => i_bls,
-               addra => address(8 downto 0),
-               dina => data_in_bus,
-               douta => bram_out,
-
-               enb => '0',
-               web => (others => '0'),
-               addrb => (others => '0'),
-               dinb => (others => '0'),
-               doutb => open
-       );
-
-       -- BCD
-       memory_bus_bcd: bus_bcd
-       port map
-       (
-               clk => clk_cpu,
+               clk_100m => clk_100m,
+               clk_50m => clk_50m,
                reset => reset,
-               en => '1',
-               ce => bcd_ce,
+               ce => tumbl_ce,
+               ta => tumbl_ta,
                rd => i_rd,
-               ta => bcd_ta,
-               data_out => bcd_out
+               bls => i_bls,
+               address => address(11 downto 0),
+               data_in => data_in_bus,
+               data_out => tumbl_out,
+
+               XMEMB_o => open,
+               XMEMB_i.clken => '1',
+               XMEMB_i.data => (others => '1'),
+               XMEMB_i.int => '0',
+               XMEMB_sel_o => open
        );
 
        -- Calibration
        memory_bus_calibration: bus_calibration
        port map
        (
-               clk => clk_cpu,
+               clk => clk_100m,
                reset => reset,
                ce => calib_ce,
                address => address(1 downto 0),
@@ -275,16 +243,19 @@ begin
                data_out => calib_out
        );
 
+       -- Filters
+       bls_f <= bls when bls = bls_d else "1111";
+       rd_f <= rd when rd = rd_d else '1';
+
        -- Bus update
-       memory_bus_update: process(clk_cpu)
+       memory_bus_update: process(clk_100m)
        begin
 
-               if clk_cpu = '1' and clk_cpu'event then
+               if clk_100m = '1' and clk_100m'event then
 
                        -- Set every signal to inactive state here
                        irc_reg_ce <= '1';
-                       bram_ce <= '1';
-                       bcd_ce <= '1';
+                       tumbl_ce <= '1';
                        calib_ce <= '1';
                        i_rd <= '1';
                        i_bls <= (others => '1');
@@ -296,23 +267,18 @@ begin
                                -- Memory Map (16-bit address @ 32-bit each)
 
                                -- Each address is seen as 32-bit entry now
-                               -- 0x0000 - 0x011F: Control dual-port BRAM
+                               -- 0x0000 - 0x0FFF: Tumbl
                                -- 0x8000 - 0x800F: IRC registers
-                               -- 0xFFFB:          32-bit BCD
                                -- 0xFFFC - 0xFFFF: Calibration
 
-                               if address < "0000000100100000" then -- Control BRAM
-                                       bram_ce <= '0';
-                                       i_ta <= bram_ta;
-                                       data_out_bus <= bram_out;
+                               if address < "0001000000000000" then -- Tumbl
+                                       tumbl_ce <= '0';
+                                       i_ta <= tumbl_ta;
+                                       data_out_bus <= tumbl_out;
                                elsif address(15 downto 4) = "100000000000" then -- IRC
                                        irc_reg_ce <= '0';
                                        i_ta <= irc_reg_ta;
                                        data_out_bus <= irc_reg_out;
-                               elsif address = "1111111111111011" then -- BCD
-                                       bcd_ce <= '0';
-                                       i_ta <= bcd_ta;
-                                       data_out_bus <= bcd_out;
                                elsif address(15 downto 2) = "11111111111111" then -- Calibration
                                        calib_ce <= '0';
                                        i_ta <= calib_ta;
@@ -320,7 +286,7 @@ begin
                                end if;
 
                                -- Reading
-                               if rd = '0' then
+                               if rd_f = '0' then
                                        if last_rd = '1' or last_address /= address then
                                                -- Getting something new
                                                -- Set internal RD to active and reset ack and latched data
@@ -344,20 +310,21 @@ begin
                                        data_read <= (others => 'X');
                                end if;
 
-                               last_rd <= rd;
+                               last_rd <= rd_f;
 
-                               -- Writing
-                               if bls /= "1111" then
-                                       if last_bls /= bls or last_address /= address then
-                                               -- Data are valid when BLS is active, broadcast it for one cycle
-                                               i_bls <= bls;
+                               -- Writing (BLS is filtered due to bus error otherwise)
+                               if bls_f /= "1111" then
+
+                                       if last_bls /= bls_f or last_address /= address then
+                                               -- Broadcast BLS for once cycle to write the data
+                                               i_bls <= bls_f;
                                                data_in_bus <= data_write;
                                        end if;
 
                                        last_address <= address;
                                end if;
 
-                               last_bls <= bls;
+                               last_bls <= bls_f;
 
                        else
 
@@ -367,6 +334,10 @@ begin
 
                        end if;
 
+                       -- Filters
+                       bls_d <= bls;
+                       rd_d <= rd;
+
                end if;
 
        end process;
@@ -389,10 +360,11 @@ begin
        end process;
 
        -- Reset
-       initialization: process(init)
+       initialization: process(init, clk_100m_locked)
        begin
 
-               reset <= not init;
+               neg_init <= not init;
+               reset <= (not init) or (not clk_100m_locked);
 
        end process;
 
index e77c8157b293d48a65ecceb97e19d3765c8ed422..408d54e29f9a41fbbf51db5a01a947fab86d02fd 100644 (file)
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
 use ieee.std_logic_arith.all;
 use ieee.std_logic_unsigned.all;
 use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
 
 -- Quadcounter (for IRC)
 
@@ -12,31 +13,27 @@ entity qcounter is
     clk      : in std_logic;
     reset    : in std_logic;
     a0, b0   : in std_logic;
+               index0   : in std_logic;
 
     qcount   : out std_logic_vector (31 downto 0);
+               qcount_index : out std_logic_vector (31 downto 0);
     a_rise, a_fall, b_rise, b_fall, ab_event: out std_logic;
     ab_error : out std_logic
   );
 end qcounter;
 
 architecture behavioral of qcounter is
-  component dff
-       port
-       (
-               clk   : in std_logic;
-               reset : in std_logic;
-               d     : in std_logic;
-               q     : out std_logic
-       );
-  end component;
 
-subtype std_logic4 is std_logic_vector (3 downto 0);
        signal last_reset: std_logic;
   signal a, b, a_prev, b_prev: std_logic;
+       signal index: std_logic;
   signal count_prev: std_logic_vector (29 downto 0);
   signal count: std_logic_vector (29 downto 0);
+       signal count_index_prev: std_logic_vector (31 downto 0);
+  signal count_index: std_logic_vector (31 downto 0);
+
 begin
-       dff_a: dff
+       dff_a: dff2
        port map
        (
                clk => clk,
@@ -45,7 +42,7 @@ begin
                q => a
        );
 
-  dff_b: dff
+  dff_b: dff2
        port map
        (
                clk => clk,
@@ -54,10 +51,21 @@ begin
                q => b
        );
 
+       dff_index: dff2
+       port map
+       (
+               clk => clk,
+               reset => '0',
+               d => index0,
+               q => index
+       );
+
        qcount(0) <= a xor b;
        qcount(1) <= b;
        qcount(31 downto 2) <= count;
 
+       qcount_index <= count_index;
+
   comb_event: process (reset, last_reset, a_prev, b_prev, a, b)
   begin
     a_rise <= '0';
@@ -81,17 +89,47 @@ begin
                end if;
   end process;
 
-  comb_count: process (reset, last_reset, a_prev, b_prev, a, b, count_prev)
+  comb_count: process (reset, last_reset, a_prev, b_prev, a, b, index, count_prev, count_index_prev)
   begin
                if reset = '1' or last_reset = '1' then
                        count <= count_prev;
+                       count_index <= count_index_prev;
+
                elsif (a_prev = '0') and (b_prev = '1') and (a = '0') and (b = '0') then
       count <= count_prev + 1;
+
+                       if index = '1' then
+                               count_index(0) <= a xor b;
+                               count_index(1) <= b;
+                               count_index(31 downto 2) <= count_prev + 1;
+                       else
+                               count_index <= count_index_prev;
+                       end if;
+
     elsif (a_prev = '0') and (b_prev = '0') and (a = '0') and (b = '1') then
       count <= count_prev - 1;
+
+                       if index = '1' then
+                               count_index(0) <= a xor b;
+                               count_index(1) <= b;
+                               count_index(31 downto 2) <= count_prev - 1;
+                       else
+                               count_index <= count_index_prev;
+                       end if;
+
     else
       count <= count_prev;
+
+                       if index = '1' then
+                               count_index(0) <= a xor b;
+                               count_index(1) <= b;
+                               count_index(31 downto 2) <= count_prev;
+                       else
+                               count_index <= count_index_prev;
+                       end if;
+
     end if;
+
   end process;
 
   seq: process (clk)
@@ -101,8 +139,10 @@ begin
                if clk = '1' and clk'event then
                        if reset = '0' then
                                count_prev <= count;
+                               count_index_prev <= count_index;
                        else
                                count_prev <= (others => '0');
+                               count_index_prev <= (others => '0');
                        end if;
                        a_prev <= a;
                        b_prev <= b;
index 3d8f813edd78b612a6ff7abfd4be9365f060e7cf..60244ff33053c4012661762a39bf75b264ac7a78 100644 (file)
@@ -10,7 +10,8 @@ ARCHITECTURE behavior OF lx_rocon_top_tb IS
 
     COMPONENT lx_rocon_top
     PORT(
-         clk_cpu : IN  std_logic;
+         --clk_cpu : IN  std_logic;
+                                clk_50m : IN  std_logic;
          cs0_xc : IN  std_logic;
          rd : IN  std_logic;
          bls : IN  std_logic_vector(3 downto 0);
@@ -38,7 +39,8 @@ ARCHITECTURE behavior OF lx_rocon_top_tb IS
 
 
    --Inputs
-   signal clk_cpu : std_logic := '0';
+   --signal clk_cpu : std_logic := '0';
+        signal clk_50m : std_logic := '0';
    signal cs0_xc : std_logic := '1';
    signal rd : std_logic := '1';
    signal bls : std_logic_vector(3 downto 0) := (others => '1');
@@ -65,13 +67,15 @@ ARCHITECTURE behavior OF lx_rocon_top_tb IS
    signal data : std_logic_vector(31 downto 0);
 
    -- Clock period definitions
-   constant clk_period : time := 20 ns;
+        constant clk_period_cpu : time := 13.8 ns;
+   constant clk_period_50m : time := 20 ns;
 
 BEGIN
 
        -- Instantiate the Unit Under Test (UUT)
    uut: lx_rocon_top PORT MAP (
-          clk_cpu => clk_cpu,
+          --clk_cpu => clk_cpu,
+                                       clk_50m => clk_50m,
           cs0_xc => cs0_xc,
           rd => rd,
           bls => bls,
@@ -97,197 +101,27 @@ BEGIN
         );
 
    -- Clock process definitions
-   clk_process :process
+--   clk_cpu_process :process
+--   begin
+--             clk_cpu <= '0';
+--             wait for clk_period_cpu/2;
+--             clk_cpu <= '1';
+--             wait for clk_period_cpu/2;
+--   end process;
+
+        clk_50m_process :process
    begin
-               clk_cpu <= '0';
-               wait for clk_period/2;
-               clk_cpu <= '1';
-               wait for clk_period/2;
+               clk_50m <= '0';
+               wait for clk_period_50m/2;
+               clk_50m <= '1';
+               wait for clk_period_50m/2;
    end process;
 
 
    -- Stimulus process
    stim_proc: process
    begin
-      -- hold reset state for 100 ns.
-      init <= '0';
-                       data <= (others => 'Z');
-      wait for 100 ns;
-                       init <= '1';
-
-      wait for clk_period*10;
-
-      -- insert stimulus here
-
-                       -- Increment IRC1
-                       irc1_a <= '1';
-                       wait for clk_period*2;
-
-                       irc1_b <= '1';
-                       wait for clk_period*2;
-
-                       irc1_a <= '0';
-                       wait for clk_period*2;
-
-                       irc1_b <= '0';
-                       wait for clk_period*2;
-
-                       irc1_a <= '1';
-                       wait for clk_period*2;
-
-                       irc1_b <= '1';
-                       wait for clk_period*2;
-
-                       irc1_a <= '0';
-                       wait for clk_period*2;
-
-                       -- Read IRC1 value (bus has 72 MHz, but signals are set to stay longer)
-                       cs0_xc <= '0';
-                       wait for clk_period;
-
-                       address <= "1000000000000000";
-                       wait for clk_period;
-
-                       rd <= '0';
-                       wait for 5*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period*3;
-
-                       -- Test BRAM: Write something and then read it back
-                       cs0_xc <= '0';
-                       wait for clk_period;
-
-                       address <= "0000000000011000";
-                       data <= "10101010101010101010101010101010";
-                       wait for clk_period;
-
-                       bls <= "0000";
-                       wait for 5*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       bls <= "1111";
-                       wait for clk_period;
-
-                       -- Now read it back
-                       cs0_xc <= '0';
-                       wait for clk_period;
-
-                       rd <= '0';
-                       wait for 5*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period*3;
-
-                       -- Now try writing to above address but with only some bytes active
-                       cs0_xc <= '0';
-                       wait for clk_period;
-
-                       address <= "0000000000011100";
-                       data <= "10101010101010101010101010101010";
-                       wait for clk_period;
-
-                       bls <= "0011";
-                       wait for 5*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       bls <= "1111";
-                       wait for clk_period;
-
-                       data <= (others => 'Z');
-                       wait for clk_period;
-
-                       -- Now read it back
-                       cs0_xc <= '0';
-                       wait for clk_period;
-
-                       rd <= '0';
-                       wait for 5*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period;
-
-                       -- Poke the bcd a few times
-                       cs0_xc <= '0';
-                       address <= "1111111111111011";
-                       wait for clk_period;
-
-                       rd <= '0';
-                       wait for 5*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period*5;
-
-                       cs0_xc <= '0';
-                       wait for clk_period;
-
-                       rd <= '0';
-                       wait for 5*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period;
-
-                       -- Read calibration register
-                       cs0_xc <= '0';
-                       address <= "1111111111111100";
-                       wait for clk_period;
-
-                       rd <= '0';
-                       wait for 8*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period*5;
-
-                       -- Write & Read calibration register
-                       cs0_xc <= '0';
-                       address <= "1111111111111110";
-                       data <= "10101010101010101010101010101010";
-                       wait for clk_period;
-
-                       bls <= "0000";
-                       wait for 8*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period*5;
-
-                       cs0_xc <= '0';
-                       address <= "1111111111111110";
-                       data <= (others => 'Z');
-                       wait for clk_period;
-
-                       rd <= '0';
-                       wait for 8*clk_period;
-
-                       cs0_xc <= '1';
-                       wait for clk_period;
-
-                       rd <= '1';
-                       wait for clk_period*5;
+      -- External ModelSim script
 
       wait;
    end process;
diff --git a/hw/tumbl b/hw/tumbl
new file mode 120000 (symlink)
index 0000000..1a543c2
--- /dev/null
+++ b/hw/tumbl
@@ -0,0 +1 @@
+../submodule/tumbl/hw
\ No newline at end of file
diff --git a/hw/xilinx_dualport_bram.vhd b/hw/xilinx_dualport_bram.vhd
new file mode 100644 (file)
index 0000000..45dc86a
--- /dev/null
@@ -0,0 +1,96 @@
+-- Xilinx dualport BRAM template, write-first mode, no delay
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.lx_rocon_pkg.all;
+
+entity xilinx_dualport_bram is
+       generic
+       (
+               -- Not all combinations are plausible for BRAMs
+               -- byte width: 8, 9, 32, 36
+               -- we_width: 1, 2, 3, 4
+               byte_width : positive := 8;
+               address_width : positive := 8;
+               we_width : positive := 4
+       );
+       port
+       (
+               clka : in std_logic;
+               rsta : in std_logic;
+               ena : in std_logic;
+               wea : in std_logic_vector((we_width-1) downto 0);
+               addra : in std_logic_vector((address_width-1) downto 0);
+               dina : in std_logic_vector(((byte_width*we_width)-1) downto 0);
+               douta : out std_logic_vector(((byte_width*we_width)-1) downto 0);
+               clkb : in std_logic;
+               rstb : in std_logic;
+               enb : in std_logic;
+               web : in std_logic_vector((we_width-1) downto 0);
+               addrb : in std_logic_vector((address_width-1) downto 0);
+               dinb : in std_logic_vector(((byte_width*we_width)-1) downto 0);
+               doutb : out std_logic_vector(((byte_width*we_width)-1) downto 0)
+       );
+end xilinx_dualport_bram;
+
+architecture Behavioral of xilinx_dualport_bram is
+       type ram is array (0 to ((2**address_width) - 1)) of std_logic_vector(((byte_width*we_width)-1) downto 0);
+       shared variable ram_block : ram := (others => (others => '0'));
+
+begin
+
+       -- CLKA process
+       ram_process_a : process(clka)
+       begin
+
+               if clka = '1' and clka'event then
+
+                       if ena = '1' then
+
+                               for i in 0 to (we_width-1) loop
+                                       if wea(i) = '1' then
+                                               ram_block(to_integer(unsigned(addra)))(((i+1)*byte_width-1) downto (i*byte_width))
+                                                       := dina(((i+1)*byte_width-1) downto (i*byte_width));
+                                       end if;
+                               end loop;
+
+                               if rsta = '1' then
+                                       douta <= (others => '0');
+                               else
+                                       douta <= ram_block(to_integer(unsigned(addra)));
+                               end if;
+
+                       end if;
+
+               end if;
+
+       end process;
+
+       -- CLKB process
+       ram_process_b : process(clkb)
+       begin
+
+               if clkb = '1' and clkb'event then
+
+                       if enb = '1' then
+
+                               for i in 0 to (we_width-1) loop
+                                       if web(i) = '1' then
+                                               ram_block(to_integer(unsigned(addrb)))(((i+1)*byte_width-1) downto (i*byte_width))
+                                                       := dinb(((i+1)*byte_width-1) downto (i*byte_width));
+                                       end if;
+                               end loop;
+
+                               if rstb = '1' then
+                                       doutb <= (others => '0');
+                               else
+                                       doutb <= ram_block(to_integer(unsigned(addrb)));
+                               end if;
+
+                       end if;
+
+               end if;
+
+       end process;
+
+end Behavioral;
diff --git a/submodule/tumbl b/submodule/tumbl
new file mode 160000 (submodule)
index 0000000..342b65f
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit 342b65f43eca19d8169829aa8d342d1424c6d323