Commit f667cd35 authored by Evangelia Gousiou's avatar Evangelia Gousiou

removed sw folder; changed general-cores branch (tom-proposed-master-feb28;…

removed sw folder; changed general-cores branch (tom-proposed-master-feb28; unused IOBs set to floating; clean up counters
parent da24db10
general-cores @ 1c2dd12b
Subproject commit 49afba4313ecab5b99d32858b82fdff171a404dc
Subproject commit 1c2dd12b1bceeab3b32b41c3522931c658ad15a7
--_________________________________________________________________________________________________
-- |
-- |TDC core| |
-- |masterFIP core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
......@@ -17,17 +17,7 @@
-- "Counter done" signal asserted simultaneous to "current count value = 0". |
-- Countdown is launched each time "counter_load_i" is asserted for one clock tick. |
-- |
-- |
-- Authors Gonzalo Penacoba (Gonzalo.Penacoba@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 04/2012 |
-- Version v0.11 |
-- Depends on |
-- |
---------------- |
-- Last changes |
-- 05/2011 v0.1 GP First version |
-- 04/2012 v0.11 EG Revamping; Comments added, signals renamed |
-- Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- |
---------------------------------------------------------------------------------------------------
......@@ -55,7 +45,6 @@ library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
--=================================================================================================
-- Entity declaration for decr_counter
--=================================================================================================
......@@ -66,17 +55,12 @@ entity decr_counter is
(width : integer := 32); -- default size
port
-- INPUTS
-- Signals from the clk_rst_manager
(clk_i : in std_logic;
rst_i : in std_logic;
-- Signals from any unit
counter_load_i : in std_logic; -- loads counter with counter_top_i value
counter_load_i : in std_logic; -- loads counter with counter_top_i
counter_top_i : in std_logic_vector(width-1 downto 0); -- counter start value
-- OUTPUTS
-- Signals to any unit
counter_o : out std_logic_vector(width-1 downto 0);
counter_is_zero_o : out std_logic); -- counter empty indication
......@@ -89,16 +73,15 @@ end decr_counter;
architecture rtl of decr_counter is
constant zeroes : unsigned(width-1 downto 0):=(others=>'0');
constant zeroes : unsigned(width-1 downto 0) :=(others=>'0');
signal one : unsigned(width-1 downto 0);
signal counter : unsigned(width-1 downto 0) := (others=>'0'); -- init to avoid sim warnings
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
decr_counting: process (clk_i)
begin
if rising_edge (clk_i) then
......
......@@ -418,7 +418,6 @@ begin
macrocyc_load_p <= macrocyc_cnt_zero_p or reg_from_mt.macrocyc_start_o or ext_sync_p;
-- note: macrocyc_start_o is a monostable, 1-clk-tick-long pulse
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
-- counter counting the number of macrocycles;
-- being a 32-bit counter, for the fastest application of 20 ms macrocycle, the counter can
......
--_________________________________________________________________________________________________
-- |
-- |The nanoFIP| |
-- |masterFIP core| |
-- |
-- CERN,BE/CO-HT |
--________________________________________________________________________________________________|
......@@ -12,15 +12,8 @@
---------------------------------------------------------------------------------------------------
-- File incr_counter.vhd |
-- Description Increasing counter with synchronous reinitialise and increase enable |
-- Authors Pablo Alvarez Sanchez (Pablo.Alvarez.Sanchez@cern.ch) |
-- Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- Date 01/2011 |
-- Version v0.011 |
-- Depends on - |
---------------- |
-- Last changes |
-- 10/2010 EG v0.01 first version |
-- 01/2011 EG v0.011 counter_full became a constant |
-- Authors Evangelia Gousiou (Evangelia.Gousiou@cern.ch) |
-- |
---------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------
......@@ -46,32 +39,22 @@
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
-- Specific library
library work;
use work.masterFIP_pkg.all; -- definitions of types, constants, entities
--=================================================================================================
-- Entity declaration for incr_counter
--=================================================================================================
entity incr_counter is
generic(g_counter_lgth : natural := 4); -- default length
generic(g_counter_lgth : natural := 32); -- default length
port(
-- INPUTS
-- nanoFIP User Interface general signal
clk_i : in std_logic; -- 40 MHz clock
-- Signals from any unit
counter_incr_i : in std_logic; -- increment enable
counter_reinit_i : in std_logic; -- reinitializes counter to 0
clk_i : in std_logic; -- 40 MHz clock
counter_incr_i : in std_logic; -- increment enable
counter_reinit_i : in std_logic; -- reinitializes counter to 0
-- OUTPUT
-- Signal to any unit
counter_o : out std_logic_vector (g_counter_lgth-1 downto 0); -- counter
counter_is_full_o : out std_logic); -- counter full indication
-- (all bits to '1')
counter_is_full_o : out std_logic); -- counter full indication, when all bits are '1'
end entity incr_counter;
......@@ -92,7 +75,6 @@ begin
---------------------------------------------------------------------------------------------------
-- Synchronous process Incr_Counter
Incr_Counter: process (clk_i)
begin
if rising_edge (clk_i) then
......@@ -107,7 +89,6 @@ begin
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
counter_o <= std_logic_vector(s_counter);
counter_is_full_o <= '1' when s_counter = c_COUNTER_FULL else '0';
......
......@@ -40,14 +40,12 @@
-- Libraries & Packages
--=================================================================================================
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions
use work.wf_package.all; -- WorldFIP specific package
use work.wf_package.all; -- WorldFIP specifics package
use work.masterfip_wbgen2_pkg.all; -- for the masterfip_wbgen2_csr records
--use work.wishbone_pkg.all;
--use work.gencores_pkg.all;
--=================================================================================================
......
......@@ -22,8 +22,10 @@
-- PAYLOAD frame field. On the other hand the FSS, CRC and FES fields are checked |
-- and validated by the masterfip_rx. |
-- As long as the rx_rst_i is not activated the deserializer probes the bus |
-- looking for a FSS; upon the detection of a FES it activates the rx_crc_wrong_p_o |
-- or rx_fss_crc_fes_ok_p_o accordingly. |
-- looking for a FSS; after the FSS detection, the deserialized bytes are packed |
-- one-by-one in 32-bit words to be provided to the MT. Upon the detection of a FES |
-- either the rx_fss_crc_fes_ok_p_o or the rx_crc_wrong_p_o is activated to signal to|
-- MT for the end of a correct or erroneous frame. |
-- |
-- RX OSC for the clock recovery |
-- |
......@@ -108,7 +110,7 @@ entity masterfip_rx is port(
rst_i : in std_logic; -- core rst, synched with clk_i
rx_rst_i : in std_logic; -- dedicated rx reset during transmission OR
-- reset pulse from the processor (MT) when for eg. a
-- reset pulse from the processor when for eg. a
-- frame is rejected during reception
-- (ex: RP_DAT > 133 bytes, wrong CTRL byte)
......@@ -176,9 +178,10 @@ architecture struc of masterfip_rx is
signal rx_byte : std_logic_vector (C_BYTE_WIDTH-1 downto 0);
-- retrieved bytes into 32-bit regs
signal byte0, byte1, byte2, byte3 : std_logic_vector(C_BYTE_WIDTH-1 downto 0);
signal zero : std_logic_vector(C_BYTE_WIDTH-1 downto 0) := (others => '0');
signal word32_num : integer range 0 to C_MAX_FRAME_WORDS-1;
-- bytes counter
signal rx_byte_index, rx_byte_index_d1 : unsigned(C_FRAME_BYTES_CNT_LGTH-1 downto 0);
signal rx_byte_index, rx_byte_index_d1 : std_logic_vector(C_FRAME_BYTES_CNT_LGTH-1 downto 0);
signal bytes_c_rst : std_logic;
......@@ -247,10 +250,10 @@ begin
---------------------------------------------------------------------------------------------------
-- bytes counter --
---------------------------------------------------------------------------------------------------
cmp_rx_bytes_cnt: wf_incr_counter
cmp_rx_bytes_cnt: incr_counter
generic map(g_counter_lgth => C_FRAME_BYTES_CNT_LGTH)
port map(
uclk_i => clk_i,
clk_i => clk_i,
counter_reinit_i => bytes_c_rst,
counter_incr_i => rx_byte_ready_p,
counter_is_full_o => open,
......@@ -258,7 +261,7 @@ begin
counter_o => rx_byte_index);
-------------------------------------------------------
bytes_c_rst <= '1' when (rst_i = '1' or rx_rst_i = '1') else '0';
rx_byte_index_o <= std_logic_vector(rx_byte_index);
rx_byte_index_o <= rx_byte_index;
---------------------------------------------------------------------------------------------------
......@@ -275,7 +278,7 @@ begin
rx_ctrl_byte_o <= (others => '0');
else
if rx_byte_ready_p = '1' then
if rx_byte_index = resize(unsigned(c_CTRL_BYTE_INDEX),9) then
if unsigned(rx_byte_index) = resize(unsigned(c_CTRL_BYTE_INDEX),9) then
rx_ctrl_byte_o <= rx_byte;
else
byte0 <= rx_byte;
......@@ -324,20 +327,21 @@ begin
if word32_num = 0 then -- only in the case of RP_FIN, where there are not enough
-- bytes to create a word; needed for keeping the MT sw generic
word32_num <= word32_num + 1;
rx_frame_o(word32_num) <= byte0 & byte1 & byte2 & byte3; --
rx_frame_o(word32_num) <= byte0 & byte1 & byte2 & byte3;
elsif (rx_byte_index-2) mod 4 = 3 then -- [CRC|CRC|BYTE|BYTE]
elsif (unsigned(rx_byte_index)-2) mod 4 = 3 then -- [CRC|CRC|BYTE|BYTE]
word32_num <= word32_num + 1;
rx_frame_o(word32_num) <= byte0 & byte1 & byte2 & byte3; -- byte 3 and byte 2 are useful
rx_frame_o(word32_num) <= byte0 & byte1 & byte2 & byte3; -- byte 3 and byte 2 are useful
elsif (rx_byte_index-2) mod 4 = 2 then -- [0|CRC|CRC|BYTE]
elsif (unsigned(rx_byte_index)-2) mod 4 = 2 then -- [0|CRC|CRC|BYTE]
word32_num <= word32_num + 1;
rx_frame_o(word32_num) <= "00000000" & byte0 & byte1 & byte2;-- one useful data byte: byte2 last byte
-- for [CRC|BYTE|BYTE|BYTE] upon rx_fss_crc_fes_ok_p a new word has been created
end if;
rx_frame_o(word32_num) <= zero & byte0 & byte1 & byte2; -- one useful data byte: byte2 last byte
end if; -- Note: for [CRC|BYTE|BYTE|BYTE], upon
-- rx_fss_crc_fes_ok_p a new word has been created
elsif (rx_byte_ready_p = '1' and (rx_byte_index_d1) > 0 and (rx_byte_index_d1) mod 4 = 0) then
elsif (rx_byte_ready_p = '1' and unsigned(rx_byte_index_d1) > 0 and unsigned(rx_byte_index_d1) mod 4 = 0) then
word32_num <= word32_num + 1;
rx_frame_o(word32_num) <= byte0 & byte1 & byte2 & byte3;
end if;
......@@ -346,7 +350,7 @@ begin
end process;
rx_word_index_o <= std_logic_vector(to_unsigned(word32_num,7));
rx_word_index_o <= std_logic_vector(to_unsigned(word32_num,C_FRAME_WORDS_CNT_LGTH));
end architecture struc;
......
......@@ -148,7 +148,8 @@ end entity masterfip_tx;
architecture struc of masterfip_tx is
-- frame bytes
signal prod_bytes_c : unsigned(C_FRAME_BYTES_CNT_LGTH-1 downto 0);
signal prod_bytes_c : std_logic_vector(C_FRAME_BYTES_CNT_LGTH-1 downto 0);
signal zero : unsigned(C_FRAME_BYTES_CNT_LGTH-1 downto 0) := (others => '0');
signal ctrl_byte, tx_byte : std_logic_vector(C_BYTE_WIDTH-1 downto 0);
signal prod_frame : tx_frame_t;
signal word32_num : integer range 0 to C_MAX_FRAME_WORDS-1;
......@@ -217,7 +218,7 @@ begin
if rst_i = '1' then
word32_num <= 0;
else
if prod_bytes_c mod 4 = 0 and tx_byte_request_p = '1' and prod_bytes_c > 0 then
if (unsigned(prod_bytes_c)) mod 4 = 0 and tx_byte_request_p = '1' and unsigned(prod_bytes_c) > 0 then
word32_num <= word32_num + 1;
end if;
end if;
......@@ -225,27 +226,27 @@ begin
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Instantiation of a wf_incr_counter for the counting of the number of the bytes that are
-- Instantiation of an incr_counter for the counting of the number of the bytes that are
-- being serialized.
cmp_tx_bytes_cnt: wf_incr_counter
cmp_tx_bytes_cnt: incr_counter
generic map(g_counter_lgth => C_FRAME_BYTES_CNT_LGTH)
port map(
uclk_i => clk_i,
clk_i => clk_i,
counter_reinit_i => tx_start_p_i,
counter_incr_i => tx_byte_request_p,
-------------------------------------------------------
counter_o => prod_bytes_c);
-------------------------------------------------------
tx_byte_index_o <= std_logic_vector(prod_bytes_c);
tx_byte_index_o <= prod_bytes_c;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Selection of one byte
word32 <= prod_frame(word32_num);
tx_byte <= ctrl_byte when prod_bytes_c = "00000000" else -- first byte to serialize is the CTRL
word32(7 downto 0) when prod_bytes_c mod 4 = 1 else -- byte(0) (lsb) of a prod_frame word
word32(15 downto 8) when prod_bytes_c mod 4 = 2 else -- byte(1) of a prod_frame word
word32(23 downto 16) when prod_bytes_c mod 4 = 3 else -- byte(2) of a prod_frame word
word32(31 downto 24); -- byte(3) (msb) of a prod_frame word
tx_byte <= ctrl_byte when unsigned(prod_bytes_c) = zero else -- first byte to serialize is the CTRL
word32(7 downto 0) when unsigned(prod_bytes_c) mod 4 = 1 else -- byte(0) (lsb) of a prod_frame word
word32(15 downto 8) when unsigned(prod_bytes_c) mod 4 = 2 else -- byte(1) of a prod_frame word
word32(23 downto 16) when unsigned(prod_bytes_c) mod 4 = 3 else -- byte(2) of a prod_frame word
word32(31 downto 24); -- byte(3) (msb) of a prod_frame word
---------------------------------------------------------------------------------------------------
......@@ -255,8 +256,8 @@ begin
port map(
uclk_i => clk_i,
nfip_rst_i => rst_i,
byte_i => tx_byte,
tx_start_p_i => tx_start_p_i,
byte_i => tx_byte,
byte_request_accept_p_i => byte_request_accept_p,
last_byte_p_i => last_data_byte_p,
tx_sched_p_buff_i => s_tx_clk_p_buff,
......@@ -287,7 +288,7 @@ begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- when s_prod_data_lgth bytes have been counted, the signal prod_data_lgth_match is activated
prod_data_lgth_match <= '1' when prod_bytes_c = unsigned(bytes_num) else '0';
prod_data_lgth_match <= '1' when prod_bytes_c = bytes_num else '0';
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
synch_signals: process (clk_i)
......
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/*.
* White Rabbit Node Core
*
* mqueue.h: MQ register definitions (Host side)
*/
#ifndef __MQUEUE_H
#define __MQUEUE_H
// Nax number of supported incoming/outgoing slots
#define MAX_MQUEUE_SLOTS 16
// HMQ base address (wrs to the base addr of the WR Node Core)
#define BASE_HMQ 0x00000
// Global Control Registers base address, relative to BASE_HMQ (SLOT_COUNT, SLOT_STATUS, interrupt control, etc).
// Common for all incoming/outgoing slots in the queue
#define MQUEUE_BASE_GCR (0x0)
// Incoming slot base address, relative to BASE_HMQ
#define MQUEUE_BASE_IN(slot) (0x4000 + (slot) * 0x400)
// Outgoung slot base address, relative to BASE_HMQ
#define MQUEUE_BASE_OUT(slot) (0x8000 + (slot) * 0x400)
// MQ slot registers, relative to the base address of each slot: MQUEUE_BASE_IN(slot_no) or MQUEUE_BASE_OUT(slot_no)
#define MQUEUE_SLOT_COMMAND 0
// Status register
#define MQUEUE_SLOT_STATUS 4
// Start of data block
#define MQUEUE_SLOT_DATA_START 8
// Layout of MQUEUE_SLOT_COMMAND register:
// Claim: prepares a slot to send a message (w/o)
#define MQUEUE_CMD_CLAIM (1<<24)
// Purge: erases all messages from a slot (w/o)
#define MQUEUE_CMD_PURGE (1<<25)
// Ready: pushes the message to the queue. (w/o)
#define MQUEUE_CMD_READY (1<<26)
// Discard: removes last message from the queue, advancing to the next one (w/o)
#define MQUEUE_CMD_DISCARD (1<<27)
// Size of the message to be sent, in words (w/o). Must be written together with the
// READY command, e.g.:
// writel (MQUEUE_CMD_READY | 10, MQUEUE_SLOT_COMMAND);
#define MQUEUE_CMD_MSG_SIZE_MASK 0xff
#define MQUEUE_CMD_MSG_SIZE_SHIFT 0
// Layout of MQUEUE_SLOT_STATUS register:
// [0] Slot is full
#define MQUEUE_SLOT_STATUS_FULL (1<<0)
// [1] Slot is empty
#define MQUEUE_SLOT_STATUS_EMPTY (1<<1)
// [15:8] Number of occupied entries
#define MQUEUE_SLOT_STATUS_OCCUPIED_SHIFT 8
#define MQUEUE_SLOT_STATUS_OCCUPIED_MASK 0xff00
// [23:16] Number of transferred words in the message currently on top of the slot
#define MQUEUE_SLOT_STATUS_MSG_SIZE_SHIFT 16
#define MQUEUE_SLOT_STATUS_MSG_SIZE_MASK 0xff0000
// [31:28] log2(number of words in the slot).
#define MQUEUE_SLOT_STATUS_LOG2_WIDTH_SHIFT 28
#define MQUEUE_SLOT_STATUS_LOG2_WIDTH_MASK 0xf0000000
// [7:2] log2(number of entries in the slot).
#define MQUEUE_SLOT_STATUS_LOG2_ENTRIES_SHIFT 2
#define MQUEUE_SLOT_STATUS_LOG2_ENTRIES_MASK 0xfc
//
// MQ Global Control Registers.Adresses relative to MQUEUE_BASE_GCR:
//
#define MQUEUE_GCR_INCOMING_STATUS_MASK (0x0000ffff)
// Number of slots in this implementation of HMQ
#define MQUEUE_GCR_SLOT_COUNT 0
// EMPTY bits of all slots in a single register (for polling/IRQ status)
#define MQUEUE_GCR_SLOT_STATUS 4
// Interrupt mask (Outgoing: EMPTY, Incoming: not EMPTY)
#define MQUEUE_GCR_IRQ_MASK 8
// IRQ Coalescing register (reserved for future use)
#define MQUEUE_GCR_IRQ_COALESCE 12
// Layout of SLOT_COUNT register
// [7:0] Number of Incoming slots
#define MQUEUE_GCR_SLOT_COUNT_N_IN_SHIFT 0
#define MQUEUE_GCR_SLOT_COUNT_N_IN_MASK 0xff
// [15:8] Number of Outgoing slots
#define MQUEUE_GCR_SLOT_COUNT_N_OUT_SHIFT 8
#define MQUEUE_GCR_SLOT_COUNT_N_OUT_MASK 0xff00
// Layout of SLOT_STATUS register
// [15:0] Outgoing slots status. Each bit indicates a NOT EMPTY status of the corresponding outgoing slot
#define MQUEUE_GCR_SLOT_STATUS_OUT_SHIFT 0
#define MQUEUE_GCR_SLOT_STATUS_OUT_MASK 0xffff
// [31:16] Incoming slots status. Each bit indicates an EMPTY status of the corresponding incoming slot
#define MQUEUE_GCR_SLOT_STATUS_IN_SHIFT 16
#define MQUEUE_GCR_SLOT_STATUS_IN_MASK 0xffff0000
// Layout of IRQ_MASK register
// [15:0] Outgoing slots status interrupt mask. Each bit enables generation of interrupt on NOT EMPTY status of the corresponding outgoing slot.
#define MQUEUE_GCR_IRQ_MASK_OUT_SHIFT 0
#define MQUEUE_GCR_IRQ_MASK_OUT_MASK 0xffff
// [31:16] Incoming slots status interrupt mask. Each bit enables generation of interrupt on EMPTY status of the corresponding incoming slot.
#define MQUEUE_GCR_IRQ_MASK_IN_SHIFT 16
#define MQUEUE_GCR_IRQ_MASK_IN_MASK 0xffff0000
// Layout of IRQ_COALSESCE register
// The register is left for future IRQ coalescing support (if ever needed)
#endif
/*
Register definitions for slave core: WR Node CPU Control/Status registers block
* File : wrn_cpu_csr.h
* Author : auto-generated by wbgen2 from wrn_cpu_csr.wb
* Created : Mon Dec 8 15:40:37 2014
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrn_cpu_csr.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WRN_CPU_CSR_WB
#define __WBGEN2_REGDEFS_WRN_CPU_CSR_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: Application ID Register */
/* definitions for register: CPU Reset Register */
/* definitions for register: CPU Enable Register */
/* definitions for register: CPU Upload Address Register */
/* definitions for field: Address in reg: CPU Upload Address Register */
#define WRN_CPU_CSR_UADDR_ADDR_MASK WBGEN2_GEN_MASK(0, 20)
#define WRN_CPU_CSR_UADDR_ADDR_SHIFT 0
#define WRN_CPU_CSR_UADDR_ADDR_W(value) WBGEN2_GEN_WRITE(value, 0, 20)
#define WRN_CPU_CSR_UADDR_ADDR_R(reg) WBGEN2_GEN_READ(reg, 0, 20)
/* definitions for register: Core Select Register */
/* definitions for register: Core Count Register */
/* definitions for register: Core Memory Size */
/* definitions for register: CPU Upload Data Register */
/* definitions for register: CPU Debug Register */
/* definitions for field: JTAG data in reg: CPU Debug Register */
#define WRN_CPU_CSR_DBG_JTAG_JDATA_MASK WBGEN2_GEN_MASK(0, 8)
#define WRN_CPU_CSR_DBG_JTAG_JDATA_SHIFT 0
#define WRN_CPU_CSR_DBG_JTAG_JDATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WRN_CPU_CSR_DBG_JTAG_JDATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for field: JTAG address in reg: CPU Debug Register */
#define WRN_CPU_CSR_DBG_JTAG_JADDR_MASK WBGEN2_GEN_MASK(8, 3)
#define WRN_CPU_CSR_DBG_JTAG_JADDR_SHIFT 8
#define WRN_CPU_CSR_DBG_JTAG_JADDR_W(value) WBGEN2_GEN_WRITE(value, 8, 3)
#define WRN_CPU_CSR_DBG_JTAG_JADDR_R(reg) WBGEN2_GEN_READ(reg, 8, 3)
/* definitions for field: JTAG reset in reg: CPU Debug Register */
#define WRN_CPU_CSR_DBG_JTAG_RSTN WBGEN2_GEN_MASK(16, 1)
/* definitions for field: JTAG TCK in reg: CPU Debug Register */
#define WRN_CPU_CSR_DBG_JTAG_TCK WBGEN2_GEN_MASK(17, 1)
/* definitions for field: JTAG Update in reg: CPU Debug Register */
#define WRN_CPU_CSR_DBG_JTAG_UPDATE WBGEN2_GEN_MASK(18, 1)
/* definitions for register: CPU Debug Message Register */
/* definitions for field: Debug message byte for the selected core in reg: CPU Debug Message Register */
#define WRN_CPU_CSR_DBG_MSG_DATA_MASK WBGEN2_GEN_MASK(0, 8)
#define WRN_CPU_CSR_DBG_MSG_DATA_SHIFT 0
#define WRN_CPU_CSR_DBG_MSG_DATA_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WRN_CPU_CSR_DBG_MSG_DATA_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: CPU Debug Messge Poll Register */
/* definitions for field: Debug Message data available in reg: CPU Debug Messge Poll Register */
#define WRN_CPU_CSR_DBG_POLL_READY_MASK WBGEN2_GEN_MASK(0, 8)
#define WRN_CPU_CSR_DBG_POLL_READY_SHIFT 0
#define WRN_CPU_CSR_DBG_POLL_READY_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WRN_CPU_CSR_DBG_POLL_READY_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* definitions for register: CPU Debug Messge Interrupt Mask Register */
/* definitions for field: Per-CPU Debug Message Interrupt Enable in reg: CPU Debug Messge Interrupt Mask Register */
#define WRN_CPU_CSR_DBG_IMSK_ENABLE_MASK WBGEN2_GEN_MASK(0, 8)
#define WRN_CPU_CSR_DBG_IMSK_ENABLE_SHIFT 0
#define WRN_CPU_CSR_DBG_IMSK_ENABLE_W(value) WBGEN2_GEN_WRITE(value, 0, 8)
#define WRN_CPU_CSR_DBG_IMSK_ENABLE_R(reg) WBGEN2_GEN_READ(reg, 0, 8)
/* [0x0]: REG Application ID Register */
#define WRN_CPU_CSR_REG_APP_ID 0x00000000
/* [0x4]: REG CPU Reset Register */
#define WRN_CPU_CSR_REG_RESET 0x00000004
/* [0x8]: REG CPU Enable Register */
#define WRN_CPU_CSR_REG_ENABLE 0x00000008
/* [0xc]: REG CPU Upload Address Register */
#define WRN_CPU_CSR_REG_UADDR 0x0000000c
/* [0x10]: REG Core Select Register */
#define WRN_CPU_CSR_REG_CORE_SEL 0x00000010
/* [0x14]: REG Core Count Register */
#define WRN_CPU_CSR_REG_CORE_COUNT 0x00000014
/* [0x18]: REG Core Memory Size */
#define WRN_CPU_CSR_REG_CORE_MEMSIZE 0x00000018
/* [0x1c]: REG CPU Upload Data Register */
#define WRN_CPU_CSR_REG_UDATA 0x0000001c
/* [0x20]: REG CPU Debug Register */
#define WRN_CPU_CSR_REG_DBG_JTAG 0x00000020
/* [0x24]: REG CPU Debug Message Register */
#define WRN_CPU_CSR_REG_DBG_MSG 0x00000024
/* [0x28]: REG CPU Debug Messge Poll Register */
#define WRN_CPU_CSR_REG_DBG_POLL 0x00000028
/* [0x2c]: REG CPU Debug Messge Interrupt Mask Register */
#define WRN_CPU_CSR_REG_DBG_IMSK 0x0000002c
#endif
/*
Register definitions for slave core: WR Node CPU Local Registers
* File : wrn_cpu_lr.h
* Author : auto-generated by wbgen2 from wrn_cpu_lr.wb
* Created : Mon Dec 8 15:40:37 2014
* Standard : ANSI C
THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wrn_cpu_lr.wb
DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
*/
#ifndef __WBGEN2_REGDEFS_WRN_CPU_LR_WB
#define __WBGEN2_REGDEFS_WRN_CPU_LR_WB
#include <inttypes.h>
#if defined( __GNUC__)
#define PACKED __attribute__ ((packed))
#else
#error "Unsupported compiler?"
#endif
#ifndef __WBGEN2_MACROS_DEFINED__
#define __WBGEN2_MACROS_DEFINED__
#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
#endif
/* definitions for register: CPU Polling Register */
/* definitions for field: HMQ Slot Status in reg: CPU Polling Register */
#define WRN_CPU_LR_POLL_HMQ_MASK WBGEN2_GEN_MASK(0, 16)
#define WRN_CPU_LR_POLL_HMQ_SHIFT 0
#define WRN_CPU_LR_POLL_HMQ_W(value) WBGEN2_GEN_WRITE(value, 0, 16)
#define WRN_CPU_LR_POLL_HMQ_R(reg) WBGEN2_GEN_READ(reg, 0, 16)
/* definitions for field: RMQ Slot Status in reg: CPU Polling Register */
#define WRN_CPU_LR_POLL_RMQ_MASK WBGEN2_GEN_MASK(16, 16)
#define WRN_CPU_LR_POLL_RMQ_SHIFT 16
#define WRN_CPU_LR_POLL_RMQ_W(value) WBGEN2_GEN_WRITE(value, 16, 16)
#define WRN_CPU_LR_POLL_RMQ_R(reg) WBGEN2_GEN_READ(reg, 16, 16)
/* definitions for register: CPU Status Register */
/* definitions for field: WR Link Up in reg: CPU Status Register */
#define WRN_CPU_LR_STAT_WR_LINK WBGEN2_GEN_MASK(0, 1)
/* definitions for field: WR Time OK in reg: CPU Status Register */
#define WRN_CPU_LR_STAT_WR_TIME_OK WBGEN2_GEN_MASK(1, 1)
/* definitions for field: WR Aux Clock OK in reg: CPU Status Register */
#define WRN_CPU_LR_STAT_WR_AUX_CLOCK_OK_MASK WBGEN2_GEN_MASK(2, 8)
#define WRN_CPU_LR_STAT_WR_AUX_CLOCK_OK_SHIFT 2
#define WRN_CPU_LR_STAT_WR_AUX_CLOCK_OK_W(value) WBGEN2_GEN_WRITE(value, 2, 8)
#define WRN_CPU_LR_STAT_WR_AUX_CLOCK_OK_R(reg) WBGEN2_GEN_READ(reg, 2, 8)
/* definitions for field: Core ID in reg: CPU Status Register */
#define WRN_CPU_LR_STAT_CORE_ID_MASK WBGEN2_GEN_MASK(28, 4)
#define WRN_CPU_LR_STAT_CORE_ID_SHIFT 28
#define WRN_CPU_LR_STAT_CORE_ID_W(value) WBGEN2_GEN_WRITE(value, 28, 4)
#define WRN_CPU_LR_STAT_CORE_ID_R(reg) WBGEN2_GEN_READ(reg, 28, 4)
/* definitions for register: TAI Cycles */
/* definitions for register: TAI Seconds */
/* definitions for register: GPIO Input */
/* definitions for register: GPIO Set */
/* definitions for register: GPIO Clear */
/* definitions for register: Debug Message Output */
/* [0x0]: REG CPU Polling Register */
#define WRN_CPU_LR_REG_POLL 0x00000000
/* [0x4]: REG CPU Status Register */
#define WRN_CPU_LR_REG_STAT 0x00000004
/* [0x8]: REG TAI Cycles */
#define WRN_CPU_LR_REG_TAI_CYCLES 0x00000008
/* [0xc]: REG TAI Seconds */
#define WRN_CPU_LR_REG_TAI_SEC 0x0000000c
/* [0x10]: REG GPIO Input */
#define WRN_CPU_LR_REG_GPIO_IN 0x00000010
/* [0x14]: REG GPIO Set */
#define WRN_CPU_LR_REG_GPIO_SET 0x00000014
/* [0x18]: REG GPIO Clear */
#define WRN_CPU_LR_REG_GPIO_CLEAR 0x00000018
/* [0x1c]: REG Debug Message Output */
#define WRN_CPU_LR_REG_DBG_CHR 0x0000001c
#endif
# and don't touch the rest unless you know what you're doing.
CROSS_COMPILE_TARGET ?= lm32-elf-
INSTALL_PREFIX ?= .
PATH_COMMON_RT ?= .
PATH_COMMON_H ?= ../include
CC = $(CROSS_COMPILE_TARGET)gcc
LD = $(CROSS_COMPILE_TARGET)ld
OBJDUMP = $(CROSS_COMPILE_TARGET)objdump
OBJCOPY = $(CROSS_COMPILE_TARGET)objcopy
SIZE = $(CROSS_COMPILE_TARGET)size
CFLAGS += -DWRNODE_RT -g -O3 -mmultiply-enabled -mbarrel-shift-enabled
CFLAGS += -I.
CFLAGS += -I$(PATH_COMMON)/rt
CFLAGS += -I$(PATH_COMMON)/include
CFLAGS += $(EXTRA_CFLAGS)
OBJS += $(PATH_COMMON)/rt/wrn-crt0.o
OBJS += $(PATH_COMMON)/rt/vsprintf-xint.o
OBJS += $(PATH_COMMON)/rt/printf.o
OBJS += $(PATH_COMMON)/rt/rt-common.o
LDSCRIPT = $(PATH_COMMON)/rt/wrnode.ld
all: $(OUTPUT)
$(OUTPUT): $(LDSCRIPT) $(OBJS)
${CC} -o $(OUTPUT).elf -nostartfiles $(OBJS) -T $(LDSCRIPT) -lgcc -lc
${OBJCOPY} --remove-section .smem -O binary $(OUTPUT).elf $(OUTPUT).bin
${OBJDUMP} -S $(OUTPUT).elf > disasm.S
$(SIZE) $(OUTPUT).elf
./genraminit $(OUTPUT).bin > $(OUTPUT).ram
clean:
rm -f $(OBJS) $(OUTPUT).bin
install:
cp $(OUTPUT).bin $(INSTALL_PREFIX)
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Alessandro Rubini <rubini@gnudd.com>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#ifndef __PP_PRINTF_H
#define __PP_PRINTF_H
#include <stdarg.h>
#define CONFIG_PRINT_BUFSIZE 128
extern int pp_printf(const char *fmt, ...)
__attribute__((format(printf,1,2)));
extern int pp_sprintf(char *s, const char *fmt, ...)
__attribute__((format(printf,2,3)));
extern int pp_vprintf(const char *fmt, va_list args);
extern int pp_vsprintf(char *buf, const char *, va_list)
__attribute__ ((format (printf, 2, 0)));
/* This is what we rely on for output */
extern int puts(const char *s);
#endif
/*
* Basic printf based on vprintf based on vsprintf
*
* Alessandro Rubini for CERN, 2011 -- public domain
* (please note that the vsprintf is not public domain but GPL)
*/
#include <stdarg.h>
#include <pp-printf.h>
static char print_buf[CONFIG_PRINT_BUFSIZE];
int pp_vprintf(const char *fmt, va_list args)
{
int ret;
ret = pp_vsprintf(print_buf, fmt, args);
puts(print_buf);
return ret;
}
int pp_sprintf(char *s, const char *fmt, ...)
{
va_list args;
int ret;
va_start(args, fmt);
ret = pp_vsprintf(s, fmt, args);
va_end(args);
return ret;
}
int pp_printf(const char *fmt, ...)
{
va_list args;
int ret;
va_start(args, fmt);
ret = pp_vprintf(fmt, args);
va_end(args);
return ret;
}
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/*.
* White Rabbit Node Core
*
* rt-common.c: common RT CPU functions
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "pp-printf.h"
#include "rt-mqueue.h"
#include "rt-common.h"
/**
* It sends a string over the debug interface
*/
int puts(const char *p)
{
char c;
int i = 0;
while (c = *(p++)) {
lr_writel(c, WRN_CPU_LR_REG_DBG_CHR);
++i;
}
/* Provide a string terminator */
lr_writel('\0', WRN_CPU_LR_REG_DBG_CHR);
return i;
}
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/*.
* White Rabbit Node Core
*
* rt-common.h: common WRN CPU definitions and routines
*/
#ifndef __RT_COMMON_H
#define __RT_COMMON_H
#include <stdint.h>
#include <stdio.h>
#include "hw/wrn_cpu_lr.h"
/* Dedicated Peripheral base */
#define CPU_DP_BASE 0x200000
/* CPU Local Registers base */
#define CPU_LR_BASE 0x100000
void rt_set_debug_slot(int slot);
/**
* Read from the Dedicated Peripheral
*/
static inline uint32_t dp_readl(uint32_t reg)
{
return *(volatile uint32_t *) ( reg + CPU_DP_BASE );
}
/**
* Write to the Dedicated Peripheral
*/
static inline void dp_writel(uint32_t value, uint32_t reg)
{
*(volatile uint32_t *) ( reg + CPU_DP_BASE ) = value;
}
/**
* Read from the CPU Local Registers
*/
static inline uint32_t lr_readl(uint32_t reg)
{
return *(volatile uint32_t *) ( reg + CPU_LR_BASE );
}
/**
* Write to the CPU Local Registers
*/
static inline uint32_t lr_writel(uint32_t value, uint32_t reg)
{
*(volatile uint32_t *) ( reg + CPU_LR_BASE ) = value;
}
/**
* Set a bit in the CPU GPIO Register
*/
static inline void gpio_set(int pin)
{
lr_writel ((1 << pin), WRN_CPU_LR_REG_GPIO_SET);
}
/**
* Clear a bit in the CPU GPIO Register
*/
static inline void gpio_clear(int pin)
{
lr_writel ((1 << pin), WRN_CPU_LR_REG_GPIO_CLEAR);
}
/**
* Wait n cycles
* fixme: use Timing Unit
*/
static inline void delay(int n)
{
int i;
for(i = 0; i < n; i++)
asm volatile("nop");
}
#endif
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/*.
* White Rabbit Node Core
*
* rt-message.h: Message assembling helper functions
*/
#ifndef __RT_MESSAGE_H
#define __RT_MESSAGE_H
#ifdef WRNODE_RT
enum wrnc_msg_direction {
WRNC_MSG_DIR_SEND = 0,
WRNC_MSG_DIR_RECEIVE = 1
};
/**
* White-Rabbit Node-Core message descriptor
*/
struct wrnc_msg {
uint32_t datalen; /**< payload length*/
volatile uint32_t *data; /**< payload */
uint32_t max_size; /**< maximum message size for chosen slot */
uint32_t offset; /**< serialization/deserialization offset */
enum wrnc_msg_direction direction; /**< serialization direction (used by wrnc_msg_x functions) */
int error; /** serialization error status */
int slot; /** concerned slot */
};
/**
* It claims an output slot. This means that you get exclusive access to
* the slot.
*/
static inline struct wrnc_msg hmq_msg_claim_out(int slot, int max_size)
{
struct wrnc_msg b;
mq_claim(0, slot);
b.data = mq_map_out_buffer(0, slot);
b.direction = WRNC_MSG_DIR_SEND;
b.max_size = max_size;
b.offset = 0;
b.datalen = 0;
b.slot = slot;
return b;
}
/**
* It claims an input slot. This mean that you get exclusive access to
* the slot
*/
static inline struct wrnc_msg hmq_msg_claim_in(int slot, int max_size)
{
struct wrnc_msg b;
b.data = mq_map_in_buffer(0, slot);
b.direction = WRNC_MSG_DIR_RECEIVE;
b.max_size = max_size;
b.datalen = max_size;
b.offset = 0;
b.slot = slot;
return b;
}
/**
* It enqueue the message in the slot, and it will be sent as soon as possible
*/
static inline void hmq_msg_send(struct wrnc_msg *buf)
{
mq_send(0, buf->slot, buf->datalen);
}
#endif
#endif
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/*.
* White Rabbit Node Core
*
* rt-mqueue.h: Message Queues definitions and functions
*/
#ifndef __RT_MQUEUE_H
#define __RT_MQUEUE_H
#define REG_LR_POLL 0x100000
/* MQ Base addresses */
#define HMQ_BASE 0x40010000
#define RMQ_BASE 0x40020000
/* MQ Slot offsets */
#define MQ_GCR (0x0)
#define MQ_IN(slot) (0x4000 + (slot) * 0x400)
#define MQ_OUT(slot) (0x8000 + (slot) * 0x400)
/* MQ Commands */
#define MQ_CMD_CLAIM (1 << 24)
#define MQ_CMD_PURGE (1 << 25)
#define MQ_CMD_READY (1 << 26)
#define MQ_CMD_DISCARD (1 << 27)
/* MQ Registers */
#define MQ_SLOT_COMMAND 0
#define MQ_SLOT_STATUS 4
#define MQ_SLOT_DATA_START 8
/**
* Remote Message Queue address
*/
struct rmq_message_addr {
uint32_t target_ip;
uint32_t target_port;
uint32_t target_offset;
};
/**
* It writes on a Message Queue register
*/
static inline void mq_writel(int remote, uint32_t val, uint32_t reg )
{
if (remote)
* (volatile uint32_t *) (RMQ_BASE + reg) = val;
else
* (volatile uint32_t *) (HMQ_BASE + reg) = val;
}
/**
* It claims a Message Queue slot
*/
static inline void mq_claim (int remote, int slot)
{
mq_writel(remote, MQ_CMD_CLAIM, MQ_OUT(slot) + MQ_SLOT_COMMAND);
}
/**
* It mark the message in the slot as Ready to send.
*/
static inline void mq_send( int remote, int slot, int count)
{
mq_writel(remote, MQ_CMD_READY | count, MQ_OUT(slot) + MQ_SLOT_COMMAND);
}
/**
* It discard (remove) a message from the given slot
*/
static inline void mq_discard (int remote, int slot)
{
mq_writel(remote, MQ_CMD_DISCARD, MQ_IN(slot));
}
/**
* It gets the output slot data field pointer
*/
static void *mq_map_out_buffer(int remote, int slot)
{
uint32_t base = remote ? RMQ_BASE : HMQ_BASE;
return (void *) (base + MQ_OUT (slot) + MQ_SLOT_DATA_START);
}
/**
* It gets the input slot data field pointer
*/
static void *mq_map_in_buffer(int remote, int slot)
{
uint32_t base = remote ? RMQ_BASE : HMQ_BASE;
return (void *) (base + MQ_IN (slot) + MQ_SLOT_DATA_START);
}
/**
* It gets the current status of the Message Queues (both Host and Remote)
*/
static inline uint32_t mq_poll()
{
return *(volatile uint32_t *) ( REG_LR_POLL );
}
/**
* It gets the current status of the Remote Message Queues
*/
static inline uint32_t rmq_poll(int slot)
{
return *(volatile uint32_t *) ( REG_LR_POLL ) & ( 1<< (16 + slot ));
}
#endif
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/*.
* White Rabbit Node Core
*
* rt-smem.h: Shared Memory definitions & API
*/
#ifndef __WRNODE_SMEM_H
#define __WRNODE_SMEM_H
#define SMEM_RANGE_ADD 0x2000
#define SMEM_RANGE_SUB 0x4000
#define SMEM_RANGE_SET 0x6000
#define SMEM_RANGE_CLEAR 0x8000
#define SMEM_RANGE_FLIP 0xa000
#define SMEM __attribute__((section(".smem")))
/**
* Perform an operation on a given pointer. Operation can be performed only
* on integer variables
*/
static inline void __smem_atomic_op(int *p, int x, unsigned int range)
{
*(volatile int *)(p + (range >> 2)) = x;
}
/**
* Add x to the value in the shared memory pointed by p
*/
static inline void smem_atomic_add(int *p, int x)
{
__smem_atomic_op(p, x, SMEM_RANGE_ADD);
}
/**
* Subtract x to the value in the shared memory pointed by p
*/
static inline void smem_atomic_sub(int *p, int x)
{
__smem_atomic_op(p, x, SMEM_RANGE_SUB);
}
/**
* Do "OR" between x and the value in the shared memory pointed by p
*/
static inline void smem_atomic_or(int *p, int x)
{
__smem_atomic_op(p, x, SMEM_RANGE_SET);
}
/**
* Do "AND ~" between x and the value in the shared memory pointed by p
*/
static inline void smem_atomic_and_not(int *p, int x)
{
__smem_atomic_op(p, x, SMEM_RANGE_CLEAR);
}
/**
* Do "XOR" between x and the value in the shared memory pointed by p
*/
static inline void smem_atomic_xor(int *p, int x)
{
__smem_atomic_op(p, x, SMEM_RANGE_FLIP);
}
#endif
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
/*.
* White Rabbit Node Core
*
* rt.h: all common stuff in a single header
*/
#ifndef __WRN_RT_H
#define __WRN_RT_H
#include <stdint.h>
#include "rt-mqueue.h"
#include "rt-message.h"
#include "rt-common.h"
#include "rt-smem.h"
#include "pp-printf.h"
#endif
/*
* vsprintf-xint: a possible free-software replacement for mprintf
*
* public domain
*/
#include <stdarg.h>
#include <stdint.h>
static const char hex[] = "0123456789abcdef";
static int number(char *out, unsigned value, int base, int lead, int wid)
{
char tmp[16];
int i = 16, ret, negative = 0;
/* No error checking at all: it is as ugly as possible */
if ((signed)value < 0 && base == 10) {
negative = 1;
value = -value;
}
while (value && i) {
tmp[--i] = hex[value % base];
value /= base;
}
if (i == 16)
tmp[--i] = '0';
if (negative && lead == ' ') {
tmp[--i] = '-';
negative = 0;
}
while (i > 16 - wid + negative)
tmp[--i] = lead;
if (negative)
tmp[--i] = '-';
ret = 16 - i;
while (i < 16)
*(out++) = tmp[i++];
return ret;
}
int pp_vsprintf(char *buf, const char *fmt, va_list args)
{
char *s, *str = buf;
int base, lead, wid;
for (; *fmt ; ++fmt) {
if (*fmt != '%') {
*str++ = *fmt;
continue;
}
base = 10;
lead = ' ';
wid = 1;
repeat:
fmt++; /* Skip '%' initially, other stuff later */
switch(*fmt) {
case '\0':
goto ret;
case '0':
lead = '0';
goto repeat;
case '*':
/* should be precision, just eat it */
base = va_arg(args, int);
/* fall through: discard unknown stuff */
default:
if (*fmt >= '1' && *fmt <= '9')
wid = *fmt - '0';
goto repeat;
/* Special cases for conversions */
case 'c': /* char: supported */
*str++ = (unsigned char) va_arg(args, int);
break;
case 's': /* string: supported */
s = va_arg(args, char *);
while (*s)
*str++ = *s++;
break;
case 'n': /* number-thus-far: not supported */
break;
case '%': /* supported */
*str++ = '%';
break;
/* integers are more or less printed */
case 'p':
case 'x':
case 'X':
base = 16;
case 'o':
if (base == 10) /* yet unchaged */
base = 8;
case 'd':
case 'i':
case 'u':
str += number(str, va_arg(args, int), base, lead, wid);
break;
}
}
ret:
*str = '\0';
return str - buf;
}
/****************************************************************************
**
** Name: crt0ram.S
**
** Description:
** Implements boot-code that calls LatticeDDInit (that calls main())
** Implements exception handlers (actually, redirectors)
**
** $Revision: $
**
** Disclaimer:
**
** This source code is intended as a design reference which
** illustrates how these types of functions can be implemented. It
** is the user's responsibility to verify their design for
** consistency and functionality through the use of formal
** verification methods. Lattice Semiconductor provides no warranty
** regarding the use or functionality of this code.
**
** --------------------------------------------------------------------
**
** Lattice Semiconductor Corporation
** 5555 NE Moore Court
** Hillsboro, OR 97214
** U.S.A
**
** TEL: 1-800-Lattice (USA and Canada)
** (503)268-8001 (other locations)
**
** web: http://www.latticesemi.com
** email: techsupport@latticesemi.com
**
** --------------------------------------------------------------------------
**
** Change History (Latest changes on top)
**
** Ver Date Description
** --------------------------------------------------------------------------
** 3.8 Apr-15-2011 Added __MICO_USER_<handler>_HANDLER__ preprocessor to
** allow customers to implement their own handlers for:
** DATA_ABORT, INST_ABORT
**
** 3.1 Jun-18-2008 Added __MICO_NO_INTERRUPTS__ preprocessor
** option to exclude invoking MicoISRHandler
** to reduce code-size in apps that don't use
** interrupts
**
** 3.0 Mar-25-2008 Added Header
**
**---------------------------------------------------------------------------
*****************************************************************************/
/*
* LatticeMico32 C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* From include/sys/signal.h */
#define SIGINT 2 /* interrupt */
#define SIGTRAP 5 /* trace trap */
#define SIGFPE 8 /* arithmetic exception */
#define SIGSEGV 11 /* segmentation violation */
//#define MICO32_FULL_CONTEXT_SAVE_RESTORE
/* Exception handlers - Must be 32 bytes long. */
.section .boot, "ax", @progbits
.global _start
_start:
.global _reset_handler
.type _reset_handler, @function
_reset_handler:
xor r0, r0, r0
wcsr IE, r0
wcsr IM, r0
mvhi r1, hi(_reset_handler)
ori r1, r1, lo(_reset_handler)
wcsr EBA, r1
calli _crt0
nop
.size _reset_handler, .-_reset_handler
.extern _irq_entry
.org 0xc0
.global _interrupt_handler
.type _interrupt_handler, @function
_interrupt_handler:
nop
.org 0x100
.global _crt0
.type _crt0, @function
_crt0:
/* Clear r0 */
xor r0, r0, r0
xor r1, r1, r1
xor r2, r2, r2
xor r3, r3, r3
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
mvi r2, 0
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
sub r3, r3, r1
/* calli memset */
mvi r1, 0
mvi r2, 0
mvi r3, 0
calli main
loopf:
bi loopf
OUTPUT_FORMAT("elf32-lm32")
ENTRY(_start)
MEMORY
{
ram :
ORIGIN = 0x00000000,
LENGTH = 32768 - 2048
stack :
ORIGIN = 32768 - 2048,
LENGTH = 2048
smem :
ORIGIN = 0x40000000,
LENGTH = 8192
}
SECTIONS
{
.boot : { *(.boot) } > ram
.text : { *(.text .text.*) } > ram =0
.rodata : { *(.rodata .rodata.*) } > ram
.data : {
*(.data .data.*)
_gp = ALIGN(16) + 0x7ff0;
} > ram
.bss : {
_fbss = .;
*(.bss .bss.*)
*(COMMON)
_ebss = .;
} > ram
.smem : { *(.smem) } > smem
PROVIDE(_endram = ORIGIN(stack));
PROVIDE(_fstack = ORIGIN(stack) + LENGTH(stack) - 4);
}
PROVIDE(mprintf = pp_printf);
OBJS = fip-test.o
OUTPUT = fip-test
PATH_COMMON = ../common/
EXTRA_CFLAGS += -I../../include
EXTRA_CFLAGS += -DRTPERFORMANCE
include $(PATH_COMMON)/rt/Makefile
/*
* This work is part of the White Rabbit Node Core project.
*
* Copyright (C) 2013-2014 CERN (www.cern.ch)
* Author: Federico Vaga <federico.vaga@cern.ch>
*
* Released according to the GNU GPL, version 2 or any later version.
*/
#include <string.h>
#include <rt.h>
#define FIP_BASE 0x10000
void rt_get_time(uint32_t *seconds, uint32_t *cycles)
{
*seconds = lr_readl(WRN_CPU_LR_REG_TAI_SEC);
*cycles = lr_readl(WRN_CPU_LR_REG_TAI_CYCLES);
}
/* magic constants below taken from Eva's Python test program */
void fip_reset()
{
dp_writel(0xCAFE0003, FIP_BASE + 0x00); // reset inactive
dp_writel(0xCAFE0000, FIP_BASE + 0x00); // reset active
dp_writel(0xCAFE0003, FIP_BASE + 0x00); // reset inactive
}
void fip_send_id_dat( uint32_t varid )
{
dp_writel(0x01, FIP_BASE + 0x2C); // rst tx
dp_writel(0x00, FIP_BASE + 0x2C); // release rst tx
dp_writel(0x3, FIP_BASE + 0xC4); // ctrl byte
dp_writel(varid, FIP_BASE + 0xC8); // varid 2 bytes
dp_writel(0x202, FIP_BASE + 0x2C); // tx start
}
int fip_rx()
{
int rx_status = dp_readl( FIP_BASE + 0x3c );
// Poll for a frame
if(rx_status & (1<<1) )
{
int n_bytes = (rx_status >> 8) & 0x1ff;
uint32_t ctrl = dp_readl( FIP_BASE + 0x40 );
uint32_t b1 = dp_readl( FIP_BASE + 0x44 );
uint32_t b2 = dp_readl( FIP_BASE + 0x48 );
uint32_t b3 = dp_readl( FIP_BASE + 0x4c );
uint32_t b4 = dp_readl( FIP_BASE + 0x40 );
pp_printf("RX bytes %d ctrl %x data %x %x %x %x\n", n_bytes, ctrl, b1, b2, b3, b4);
dp_writel(0x01, FIP_BASE + 0x3C); // rst rx
dp_writel(0x00, FIP_BASE + 0x3C); // release rst rx
}
}
main()
{
int i = 0;
fip_reset();
fip_send_id_dat(0x310);
for(;;)
{
i++;
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -213,9 +213,6 @@ NET "ext_sync_term_en_o" IOSTANDARD = "LVCMOS25";
NET "ext_sync_i" LOC = T8;
NET "ext_sync_i" IOSTANDARD = "LVCMOS25";
NET "ext_sync_tst_n_o" LOC = U8;
NET "ext_sync_tst_n_o" IOSTANDARD = "LVCMOS25";
NET "ext_sync_oe_n_o" LOC = W6;
NET "ext_sync_oe_n_o" IOSTANDARD = "LVCMOS25";
......@@ -231,12 +228,6 @@ NET "adc_m5v_shdn_n_o" IOSTANDARD = "LVCMOS25";
NET "adc_5v_en_n_o" LOC = R8;
NET "adc_5v_en_n_o" IOSTANDARD = "LVCMOS25";
NET "adc_prim_conn_n_o" LOC = V7;
NET "adc_prim_conn_n_o" IOSTANDARD = "LVCMOS25";
NET "adc_sec_conn_n_o" LOC = W8;
NET "adc_sec_conn_n_o" IOSTANDARD = "LVCMOS25";
NET "led_tx_err_n_o" LOC = C19;
NET "led_tx_err_n_o" IOSTANDARD = "LVCMOS25";
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment