Commit 3a54a6b8 authored by Tristan Gingold's avatar Tristan Gingold

Add urv for plc.

parent 8f5e366a
files = [ "fip_urv.vhd", "fip_urv_regs.vhd" ]
files = [ "fip_urv.vhd", "fip_urv_regs.vhd",
"plc_urv.vhd", "plc_urv_regs.vhd" ]
......@@ -12,10 +12,10 @@ memory-map:
access: rw
children:
- field:
name: rst
name: rstn
description: Put the PLC processor on reset
range: 0
preset: 1
preset: 0
- reg:
name: fip_status
description: Status bits from NanoFIP
......@@ -46,6 +46,10 @@ memory-map:
- field:
name: acc
range: 0
- submap:
name: mailboxes
filename: "mbox_regs.cheby"
include: True
- reg:
name: presence
description: presence lines for boards
......
-- Do not edit. Generated on Tue Feb 11 16:17:59 2020 by tgingold
-- Do not edit. Generated on Fri Feb 14 11:50:20 2020 by tgingold
-- With Cheby 1.4.dev0 and these options:
-- -i fip_urv_regs.cheby --gen-hdl fip_urv_regs.vhd
......@@ -17,7 +17,7 @@ entity fip_urv_regs is
-- PLC processor control
-- Put the PLC processor on reset
plc_ctrl_rst_o : out std_logic;
plc_ctrl_rstn_o : out std_logic;
-- Status bits from NanoFIP
fip_status_var1_rdy_i : in std_logic;
......@@ -29,6 +29,18 @@ entity fip_urv_regs is
-- Set access to var 1
fip_var3_acc_o : out std_logic;
-- Mailbox to the fip urv
mailboxes_mboxout_o : out std_logic_vector(31 downto 0);
mailboxes_mboxout_wr_o : out std_logic;
-- Mailbox from the fip urv
mailboxes_mboxin_i : in std_logic_vector(31 downto 0);
mailboxes_mboxin_rd_o : out std_logic;
-- Status for mailboxes
mailboxes_status_mbin_i : in std_logic;
mailboxes_status_mbout_i : in std_logic;
-- presence lines for boards
presence_en_i : in std_logic_vector(7 downto 0);
......@@ -79,7 +91,7 @@ architecture syn of fip_urv_regs is
signal ack_int : std_logic;
signal wb_rip : std_logic;
signal wb_wip : std_logic;
signal plc_ctrl_rst_reg : std_logic;
signal plc_ctrl_rstn_reg : std_logic;
signal plc_ctrl_wreq : std_logic;
signal plc_ctrl_wack : std_logic;
signal fip_var1_acc_reg : std_logic;
......@@ -88,6 +100,7 @@ architecture syn of fip_urv_regs is
signal fip_var3_acc_reg : std_logic;
signal fip_var3_wreq : std_logic;
signal fip_var3_wack : std_logic;
signal mailboxes_mboxout_wreq : std_logic;
signal leds_val_reg : std_logic_vector(5 downto 0);
signal leds_wreq : std_logic;
signal leds_wack : std_logic;
......@@ -163,15 +176,15 @@ begin
end process;
-- Register plc_ctrl
plc_ctrl_rst_o <= plc_ctrl_rst_reg;
plc_ctrl_rstn_o <= plc_ctrl_rstn_reg;
process (clk_i) begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
plc_ctrl_rst_reg <= '1';
plc_ctrl_rstn_reg <= '0';
plc_ctrl_wack <= '0';
else
if plc_ctrl_wreq = '1' then
plc_ctrl_rst_reg <= wr_dat_d0(0);
plc_ctrl_rstn_reg <= wr_dat_d0(0);
end if;
plc_ctrl_wack <= plc_ctrl_wreq;
end if;
......@@ -212,6 +225,14 @@ begin
end if;
end process;
-- Register mailboxes_mboxout
mailboxes_mboxout_o <= wr_dat_d0;
mailboxes_mboxout_wr_o <= mailboxes_mboxout_wreq;
-- Register mailboxes_mboxin
-- Register mailboxes_status
-- Register presence
-- Register leds
......@@ -295,6 +316,7 @@ begin
plc_ctrl_wreq <= '0';
fip_var1_wreq <= '0';
fip_var3_wreq <= '0';
mailboxes_mboxout_wreq <= '0';
leds_wreq <= '0';
fip_reg_we <= '0';
plc_mem_we <= '0';
......@@ -319,34 +341,44 @@ begin
fip_var3_wreq <= wr_req_d0;
wr_ack_int <= fip_var3_wack;
when "000000100" =>
-- Reg presence
-- Reg mailboxes_mboxout
mailboxes_mboxout_wreq <= wr_req_d0;
wr_ack_int <= wr_req_d0;
when "000000101" =>
-- Reg mailboxes_mboxin
wr_ack_int <= wr_req_d0;
when "000000110" =>
-- Reg mailboxes_status
wr_ack_int <= wr_req_d0;
when "000001000" =>
-- Reg presence
wr_ack_int <= wr_req_d0;
when "000001001" =>
-- Reg leds
leds_wreq <= wr_req_d0;
wr_ack_int <= leds_wack;
when "000001000" =>
when "000010000" =>
-- Reg boards_pins_0
wr_ack_int <= wr_req_d0;
when "000001001" =>
when "000010001" =>
-- Reg boards_pins_1
wr_ack_int <= wr_req_d0;
when "000001010" =>
when "000010010" =>
-- Reg boards_pins_2
wr_ack_int <= wr_req_d0;
when "000001011" =>
when "000010011" =>
-- Reg boards_pins_3
wr_ack_int <= wr_req_d0;
when "000001100" =>
when "000010100" =>
-- Reg boards_pins_4
wr_ack_int <= wr_req_d0;
when "000001101" =>
when "000010101" =>
-- Reg boards_pins_5
wr_ack_int <= wr_req_d0;
when "000001110" =>
when "000010110" =>
-- Reg boards_pins_6
wr_ack_int <= wr_req_d0;
when "000001111" =>
when "000010111" =>
-- Reg boards_pins_7
wr_ack_int <= wr_req_d0;
when others =>
......@@ -369,9 +401,10 @@ begin
end process;
-- Process for read requests.
process (adr_int, rd_req_int, plc_ctrl_rst_reg, fip_status_var1_rdy_i, fip_status_var3_rdy_i, fip_var1_acc_reg, fip_var3_acc_reg, presence_en_i, leds_val_reg, boards_pins_0_i, boards_pins_1_i, boards_pins_2_i, boards_pins_3_i, boards_pins_4_i, boards_pins_5_i, boards_pins_6_i, boards_pins_7_i, fip_reg_i.dat, fip_reg_rack, plc_mem_i.dat, plc_mem_rack) begin
process (adr_int, rd_req_int, plc_ctrl_rstn_reg, fip_status_var1_rdy_i, fip_status_var3_rdy_i, fip_var1_acc_reg, fip_var3_acc_reg, mailboxes_mboxin_i, mailboxes_status_mbin_i, mailboxes_status_mbout_i, presence_en_i, leds_val_reg, boards_pins_0_i, boards_pins_1_i, boards_pins_2_i, boards_pins_3_i, boards_pins_4_i, boards_pins_5_i, boards_pins_6_i, boards_pins_7_i, fip_reg_i.dat, fip_reg_rack, plc_mem_i.dat, plc_mem_rack) begin
-- By default ack read requests
rd_dat_d0 <= (others => 'X');
mailboxes_mboxin_rd_o <= '0';
fip_reg_re <= '0';
plc_mem_re <= '0';
case adr_int(13 downto 13) is
......@@ -382,7 +415,7 @@ begin
when "000000000" =>
-- Reg plc_ctrl
rd_ack_d0 <= rd_req_int;
rd_dat_d0(0) <= plc_ctrl_rst_reg;
rd_dat_d0(0) <= plc_ctrl_rstn_reg;
rd_dat_d0(31 downto 1) <= (others => '0');
when "000000001" =>
-- Reg fip_status
......@@ -401,44 +434,58 @@ begin
rd_dat_d0(0) <= fip_var3_acc_reg;
rd_dat_d0(31 downto 1) <= (others => '0');
when "000000100" =>
-- Reg mailboxes_mboxout
rd_ack_d0 <= rd_req_int;
when "000000101" =>
-- Reg mailboxes_mboxin
mailboxes_mboxin_rd_o <= rd_req_int;
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= mailboxes_mboxin_i;
when "000000110" =>
-- Reg mailboxes_status
rd_ack_d0 <= rd_req_int;
rd_dat_d0(0) <= mailboxes_status_mbin_i;
rd_dat_d0(1) <= mailboxes_status_mbout_i;
rd_dat_d0(31 downto 2) <= (others => '0');
when "000001000" =>
-- Reg presence
rd_ack_d0 <= rd_req_int;
rd_dat_d0(7 downto 0) <= presence_en_i;
rd_dat_d0(31 downto 8) <= (others => '0');
when "000000101" =>
when "000001001" =>
-- Reg leds
rd_ack_d0 <= rd_req_int;
rd_dat_d0(5 downto 0) <= leds_val_reg;
rd_dat_d0(31 downto 6) <= (others => '0');
when "000001000" =>
when "000010000" =>
-- Reg boards_pins_0
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_0_i;
when "000001001" =>
when "000010001" =>
-- Reg boards_pins_1
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_1_i;
when "000001010" =>
when "000010010" =>
-- Reg boards_pins_2
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_2_i;
when "000001011" =>
when "000010011" =>
-- Reg boards_pins_3
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_3_i;
when "000001100" =>
when "000010100" =>
-- Reg boards_pins_4
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_4_i;
when "000001101" =>
when "000010101" =>
-- Reg boards_pins_5
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_5_i;
when "000001110" =>
when "000010110" =>
-- Reg boards_pins_6
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_6_i;
when "000001111" =>
when "000010111" =>
-- Reg boards_pins_7
rd_ack_d0 <= rd_req_int;
rd_dat_d0 <= boards_pins_7_i;
......
cheby -i fip_urv_regs.cheby --gen-hdl fip_urv_regs.vhd
cheby -i plc_urv_regs.cheby --gen-hdl plc_urv_regs.vhd
memory-map:
bus: wb-32-be
name: mbox_regs
description: Registers for mailboxes
children:
- reg:
name: mboxout
description: Mailbox to the fip urv
width: 32
access: wo
x-hdl:
write-strobe: True
type: wire
- reg:
name: mboxin
description: Mailbox from the fip urv
width: 32
access: ro
x-hdl:
read-strobe: True
type: wire
- reg:
name: status
description: Status for mailboxes
width: 32
access: ro
children:
- field:
name: mbin
range: 0
- field:
name: mbout
range: 1
--------------------------------------------------------------------------------
-- CERN BE-CO-HT
-- Mock Turtle
-- https://gitlab.cern.ch/coht/mockturtle
--------------------------------------------------------------------------------
--
-- unit name: mt_urv_wrapper
--
-- description: A small wrapper for the URV encompassing the internal RAM and
-- access to the RAM through CPU CSR register block.
--
--------------------------------------------------------------------------------
-- Copyright CERN 2014-2018
--------------------------------------------------------------------------------
-- Copyright and related rights are licensed under the Solderpad Hardware
-- License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
-- http://solderpad.org/licenses/SHL-2.0.
-- Unless required by applicable law or agreed to in writing, software,
-- hardware and materials distributed under this License is distributed on an
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions
-- and limitations under the License.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.genram_pkg.all;
use work.memory_loader_pkg.all;
use work.wishbone_pkg.all;
use work.urv_pkg.all;
entity plc_urv is
generic(
g_IRAM_LOG_SIZE : natural := 10;
g_DRAM_LOG_SIZE : natural := 12);
port(
clk_sys_i : in std_logic;
rst_n_i : in std_logic;
-- WB port to write to iram.
ram_wb_i : in t_wishbone_slave_in;
ram_wb_o : out t_wishbone_slave_out;
-- Peripheral.
dwb_o : out t_wishbone_master_out;
dwb_i : in t_wishbone_master_in);
end plc_urv;
architecture arch of plc_urv is
signal cpu_rst : std_logic;
signal cpu_rst_d : std_logic;
signal im_addr : std_logic_vector(31 downto 0);
signal im_data : std_logic_vector(31 downto 0);
signal im_valid : std_logic;
signal dm_addr, dm_data_s, dm_data_l : std_logic_vector(31 downto 0);
signal dm_data_select : std_logic_vector(3 downto 0);
signal dm_load, dm_store, dm_load_done, dm_store_done : std_logic;
signal dm_cycle_in_progress, dm_is_wishbone : std_logic;
signal dm_mem_rdata, dm_wb_rdata : std_logic_vector(31 downto 0);
signal dm_wb_write, dm_select_wb : std_logic;
signal dm_data_write : std_logic;
signal dwb_out : t_wishbone_master_out;
begin
dwb_o <= dwb_out;
U_cpu_core : urv_cpu
generic map (
g_timer_frequency => 0,
g_with_hw_debug => 0,
g_with_hw_mul => 0,
g_with_hw_div => 0
)
port map (
clk_i => clk_sys_i,
rst_i => cpu_rst,
irq_i => '0',
im_addr_o => im_addr,
im_data_i => im_data,
im_valid_i => im_valid,
dm_addr_o => dm_addr,
dm_data_s_o => dm_data_s,
dm_data_l_i => dm_data_l,
dm_data_select_o => dm_data_select,
dm_store_o => dm_store,
dm_load_o => dm_load,
dm_load_done_i => dm_load_done,
dm_store_done_i => dm_store_done,
dbg_force_i => '0',
dbg_enabled_o => open,
dbg_insn_i => x"0000_0000",
dbg_insn_set_i => '0',
dbg_insn_ready_o => open,
dbg_mbx_data_i => x"0000_0000",
dbg_mbx_write_i => '0',
dbg_mbx_data_o => open);
dm_data_write <= not dm_is_wishbone and dm_store;
p_iram: process (clk_sys_i)
is
constant IRAM_WSIZE : natural := 2 ** (g_IRAM_LOG_SIZE - 2);
variable mem : t_ram32_type(0 to IRAM_WSIZE - 1);
begin
if rising_edge(clk_sys_i) then
im_data <= mem (to_integer(unsigned(im_addr(g_IRAM_LOG_SIZE - 1 downto 2))));
ram_wb_o.ack <= '0';
if ram_wb_i.stb = '1' and ram_wb_i.cyc = '1' and ram_wb_i.we = '1' then
mem (to_integer(unsigned(ram_wb_i.adr(g_IRAM_LOG_SIZE - 1 downto 2)))) := ram_wb_i.dat;
ram_wb_o.ack <= '1';
end if;
end if;
end process;
ram_wb_o.dat <= (others => 'X');
ram_wb_o.err <= '0';
ram_wb_o.rty <= '0';
ram_wb_o.stall <= '0';
-- 1st MByte of the mem is the IRAM
dm_is_wishbone <= '1' when dm_addr(31 downto 20) /= x"000" else '0';
dm_data_write <= not dm_is_wishbone and dm_store;
dm_data_l <= dm_wb_rdata when dm_select_wb = '1' else dm_mem_rdata;
p_ram: process (clk_sys_i)
is
variable mem : t_ram32_type (2**(g_DRAM_LOG_SIZE - 2) - 1 downto 0);
variable addr : natural range mem'range;
begin
if rising_edge(clk_sys_i) then
addr := to_integer(unsigned(dm_addr(g_DRAM_LOG_SIZE - 1 downto 2)));
dm_mem_rdata <= mem(addr);
if dm_data_write = '1' then
for i in 0 to 3 loop
if dm_data_select (i) = '1' then
mem(addr)(8*i + 7 downto 8*i) := dm_data_s(8*i + 7 downto 8*i);
end if;
end loop;
end if;
end if;
end process;
-- Wishbone bus arbitration / internal RAM access
p_wishbone_master : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_i = '0' then
dwb_out.cyc <= '0';
dwb_out.stb <= '0';
dwb_out.adr <= (others => '0');
dwb_out.sel <= x"0";
dwb_out.we <= '0';
dwb_out.dat <= (others => '0');
dm_cycle_in_progress <= '0';
dm_load_done <= '0';
dm_store_done <= '0';
dm_select_wb <= '0';
else
if dm_cycle_in_progress = '0' then
if dm_is_wishbone = '0' then
-- Internal access
if dm_store = '1' then
dm_load_done <= '0';
dm_store_done <= '1';
dm_select_wb <= '0';
elsif dm_load = '1' then
dm_load_done <= '1';
dm_store_done <= '0';
dm_select_wb <= '0';
else
dm_store_done <= '0';
dm_load_done <= '0';
dm_select_wb <= '0';
end if;
else
-- Wishbone access
if dm_load = '1' or dm_store = '1' then
dwb_out.cyc <= '1';
dwb_out.stb <= '1';
dwb_out.we <= dm_store;
dm_wb_write <= dm_store;
dwb_out.adr <= dm_addr;
dwb_out.dat <= dm_data_s;
dwb_out.sel <= dm_data_select;
dm_load_done <= '0';
dm_store_done <= '0';
dm_cycle_in_progress <= '1';
else
dm_store_done <= '0';
dm_load_done <= '0';
dm_cycle_in_progress <= '0';
end if;
end if;
else
-- Wishbone transfer in progress.
if dwb_i.stall = '0' then
dwb_out.stb <= '0';
end if;
if dwb_i.ack = '1' then
if dm_wb_write = '0' then
dm_wb_rdata <= dwb_i.dat;
dm_select_wb <= '1';
dm_load_done <= '1';
else
dm_store_done <= '1';
dm_select_wb <= '0';
end if;
dm_cycle_in_progress <= '0';
dwb_out.cyc <= '0';
end if;
end if;
end if;
end if;
end process p_wishbone_master;
cpu_rst <= not rst_n_i;
p_im_valid : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if cpu_rst = '1' then
im_valid <= '0';
cpu_rst_d <= '1';
else
cpu_rst_d <= cpu_rst;
im_valid <= (not cpu_rst_d);
end if;
end if;
end process p_im_valid;
end arch;
memory-map:
bus: wb-32-be
name: plc_urv_regs
description: Registers for the plc urv
x-hdl:
busgroup: True
children:
- submap:
name: mailboxes
filename: "mbox_regs.cheby"
include: True
- reg:
name: presence
description: presence lines for boards
width: 32
access: ro
children:
- field:
name: en
range: 7-0
- repeat:
name: loops
count: 8
children:
- reg:
name: pins
width: 32
access: ro
- repeat:
name: relays
count: 8
children:
- reg:
name: pins
width: 32
access: rw
This diff is collapsed.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity top_sim is
end top_sim;
architecture behav of top_sim is
signal clk_25m_i : std_logic := '0';
signal por_n_b : std_logic := 'Z';
signal button_i : std_logic;
signal dati : std_logic_vector(7 downto 0);
signal dato : std_logic_vector(7 downto 0);
signal adr : std_logic_vector(9 downto 0);
signal stb : std_logic;
signal wclk : std_logic;
signal we : std_logic;
signal cyc : std_logic;
signal ack : std_logic;
signal rst : std_logic;
signal rstin_o : std_logic;
signal nostat_o : std_logic;
signal var3_acc : std_logic;
signal var3_rdy : std_logic;
signal var2_acc_o : std_logic;
signal var2_rdy_i : std_logic;
signal var1_acc : std_logic;
signal var1_rdy : std_logic;
signal p3_lgth_o : std_logic_vector(2 downto 0);
signal diag_scl_b : std_logic;
signal diag_sda_b : std_logic;
signal s1_p_b : std_logic_vector(15 downto 0);
signal s1_n_b : std_logic_vector(15 downto 0);
signal s1_en_i : std_logic;
signal s2_p_b : std_logic_vector(13 downto 0);
signal s2_n_b : std_logic_vector(13 downto 0);
signal s2_en_i : std_logic;
signal s3_p_b : std_logic_vector(13 downto 0);
signal s3_n_b : std_logic_vector(13 downto 0);
signal s3_en_i : std_logic;
signal s4_p_b : std_logic_vector(13 downto 0);
signal s4_n_b : std_logic_vector(13 downto 0);
signal s4_en_i : std_logic;
signal s5_p_b : std_logic_vector(13 downto 0);
signal s5_n_b : std_logic_vector(13 downto 0);
signal s5_en_i : std_logic;
signal s7_p_b : std_logic_vector(15 downto 0);
signal s7_n_b : std_logic_vector(15 downto 0);
signal s7_en_i : std_logic;
signal leds_o : std_logic_vector(5 downto 0);
type sultochar_type is array (std_ulogic) of character;
constant sultochar : sultochar_type := "UX01ZWLH-";
function image (v : std_logic_vector) return string
is
variable res : string (1 to v'length);
variable p : natural := 1;
begin
for i in v'range loop
res (p) := sultochar (v (i));
p := p + 1;
end loop;
return res;
end image;
begin
clk_25m_i <= not clk_25m_i after 20 ns;
button_i <= '1', '0' after 80 ns;
por_n_b <= 'H';
process (leds_o)
begin
report "Leds: " & image (leds_o) severity note;
end process;
var3_rdy <= '1';
diot_urv_top_1: entity work.diot_urv_top
port map (
clk_25m_i => clk_25m_i,
por_n_b => por_n_b,
button_i => button_i,
dat_i => dati,
dat_o => dato,
adr_o => adr,
stb_o => stb,
wclk_o => wclk,
we_o => we,
cyc_o => cyc,
ack_i => ack,
rst_o => rst,
rstin_o => rstin_o,
nostat_o => nostat_o,
var3_acc_o => var3_acc,
var3_rdy_i => var3_rdy,
var2_acc_o => var2_acc_o,
var2_rdy_i => var2_rdy_i,
var1_acc_o => var1_acc,
var1_rdy_i => var1_rdy,
p3_lgth_o => p3_lgth_o,
diag_scl_b => diag_scl_b,
diag_sda_b => diag_sda_b,
s1_p_b => s1_p_b,
s1_n_b => s1_n_b,
s1_en_i => s1_en_i,
s2_p_b => s2_p_b,
s2_n_b => s2_n_b,
s2_en_i => s2_en_i,
s3_p_b => s3_p_b,
s3_n_b => s3_n_b,
s3_en_i => s3_en_i,
s4_p_b => s4_p_b,
s4_n_b => s4_n_b,
s4_en_i => s4_en_i,
s5_p_b => s5_p_b,
s5_n_b => s5_n_b,
s5_en_i => s5_en_i,
s7_p_b => s7_p_b,
s7_n_b => s7_n_b,
s7_en_i => s7_en_i,
leds_o => leds_o);
process (wclk) is
subtype t_byte is std_logic_vector (7 downto 0);
type t_byte_arr is array (natural range <>) of t_byte;
subtype t_cmd is t_byte_arr (0 to 71);
type t_cmds is array (natural range <>) of t_cmd;
constant cmds : t_cmds (0 to 3) :=
(-- First command: read mbox in.
0 => (x"02", x"4b", x"00", x"00",
x"14", x"00", x"10", x"00",
others => x"00"),
-- Second command: load plc
1 => (x"10", x"2f", x"00", x"00",
x"00", x"20", x"10", x"00",
x"93", x"01", x"00", x"03",
x"17", x"01", x"01", x"00",
x"13", x"01", x"c1", x"3f",
x"ef", x"00", x"c0", x"00",
x"ef", x"00", x"c0", x"01",
x"6f", x"f0", x"df", x"ff",
x"b7", x"57", x"34", x"12",
x"37", x"07", x"10", x"00",
x"93", x"87", x"87", x"67",
x"23", x"20", x"f7", x"00",
x"67", x"80", x"00", x"00",
x"67", x"80", x"00", x"00",
others => x"00"),
-- Third command: deassert plc reset
2 => (x"01", x"4b", x"00", x"00",
x"00", x"00", x"10", x"00",
x"01", x"00", x"00", x"00",
others => x"00"),
-- Fourth command: read mbox
3 => (x"01", x"4b", x"00", x"00",
x"00", x"00", x"10", x"00",
x"01", x"00", x"00", x"00",
others => x"00"));
variable idx : natural := 0;
variable addr : natural;
variable ans : t_byte_arr (0 to 7);
variable var3_acc_d : std_logic;
begin
if rising_edge(wclk) then
if rst = '1' then
idx := 0;
var1_rdy <= '1';
var3_acc_d := '0';
else
if cyc = '1' and stb = '1' then
addr := to_integer (unsigned (adr(6 downto 0)));
report "got WB read from " & natural'image (addr);
if we = '0' and adr (9 downto 7) = "000" then
dati <= cmds(idx)(addr - 2);
ack <= '1';
elsif we = '1' and adr (9 downto 7) = "010" then
ans (addr - 2) := dato;
ack <= '1';
end if;
else
ack <= '0';
end if;
if var3_acc = '0' and var3_acc_d = '1' then
report "got an answer";
var1_rdy <= '0';
idx := idx + 1;
else
if idx <= cmds'high then
var1_rdy <= '1';
end if;
end if;
var3_acc_d := var3_acc;
end if;
end if;
end process;
end;
......@@ -13,7 +13,7 @@ files = ["diot_urv_top.vhd"]
#include_dirs = [ "../../sim", "../../sim/include", "../../sim/include/wb" ]
modules = {
"local" : ["../../rtl", "../../rtl/urv_wic"],
"local" : ["../../rtl/urv_wic"],
"git": [ "git://ohwr.org/project/general-cores.git",
"git://ohwr.org/project/urv-core.git"]}
# "../../ip_cores/nanofip-gateware/top",
......
This diff is collapsed.
......@@ -13,8 +13,8 @@ MFIP ?= $(REPO_PARENT)
TRTL ?= $(REPO_PARENT)/mockturtle/software
# use delivered version
CFLAGS += --std=gnu99 -O
CFLAGS += -Wall -ggdb $(DBG) -I. -I$(MFIP) -I$(MFIP)/include -I$(MFIP)/lib
CFLAGS += --std=gnu99 -g
CFLAGS += -Wall -I. -I$(MFIP) -I$(MFIP)/include -I$(MFIP)/lib
CFLAGS += -D__GIT_VER__="\"$(GIT_VER)\"" -D__GIT_USR__="\"$(GIT_USR)\""
CXXFLAGS = $(CFLAGS) -std=c++11
LDLIBS += -Wl,-Bstatic -L$(MFIP)/lib -L$(TRTL)/lib
......
......@@ -28,6 +28,8 @@
#include <sys/time.h>
#include <unistd.h>
#include <elf.h>
#include <masterfip/libmasterfip.h>
#include "fip_urv_cmd.h"
......@@ -43,7 +45,7 @@ static const uint16_t ftb_var_id[2] = {
struct urv_cmd {
unsigned char cmd;
unsigned char id; /* Set when command is sent. */
unsigned char len; /* Length of args. */
unsigned char len; /* Length of args (in bytes). */
unsigned char args[68];
int (*cb)(struct urv_cmd *, unsigned char *rep);
......@@ -105,7 +107,7 @@ static int read_vars(void)
}
if (ftb->idx_cmd < ftb->nbr_cmds) {
struct urv_cmd *cmd = &ftb->cmds[ftb->idx_cmd];
if (pvar->buffer[0] == cmd->cmd
&& pvar->buffer[1] == cmd->id) {
int res;
......@@ -187,7 +189,10 @@ static int update_vars(void)
pvar->buffer[1] = cmd->id;
memcpy (pvar->buffer + 4, cmd->args, cmd->len);
printf ("Send command 0x%02x, len=%d\n", cmd->cmd, pvar->bsz);
printf ("Send 0x%02x, len=%d:", cmd->cmd, pvar->bsz);
for (unsigned j = 0; j < 4 + cmd->len; j++)
printf (" %02x", pvar->buffer[j]);
printf ("\n");
ftb->waitrep = 1;
}
......@@ -378,12 +383,195 @@ static int append_command(struct ftb_dev *dev, const struct urv_cmd *cmd)
return 0;
}
static void word_pack(unsigned char *buf, unsigned val)
{
buf[0] = val;
buf[1] = val >> 8;
buf[2] = val >> 16;
buf[3] = val >> 24;
}
static unsigned word_unpack(unsigned char *buf)
{
unsigned val;
val = buf[0];
val |= (buf[1] << 8);
val |= (buf[2] << 16);
val |= (buf[3] << 24);
return val;
}
static int cb_get_leds (struct urv_cmd *cmd, unsigned char *rep)
{
printf ("Led status: 0x%02x\n", rep[4]);
return 0;
}
static int cb_read_word (struct urv_cmd *cmd, unsigned char *rep)
{
printf ("Value: 0x%08x\n", word_unpack(&rep[4]));
return 0;
}
static Elf32_Half read_elf_half (const Elf32_Half *v)
{
const unsigned char *p = (const unsigned char *)v;
return p[0] | (p[1] << 8); /* LE */
}
static Elf32_Word read_elf_word (const Elf32_Word *v)
{
const unsigned char *p = (const unsigned char *)v;
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); /* LE */
}
struct load_cb_data {
unsigned char *buf;
size_t len;
size_t off;
};
static int load_cb_prepare(struct urv_cmd *cmd);
static int cb_load (struct urv_cmd *cmd, unsigned char *rep)
{
if (load_cb_prepare (cmd) == 0)
return 0;
return 1;
}
static int load_cb_prepare(struct urv_cmd *cmd)
{
struct load_cb_data *dat = (struct load_cb_data *)cmd->cb_data;
unsigned l;
if (dat->off >= dat->len) {
free (dat->buf);
free (dat);
return 0;
}
l = dat->len - dat->off;
if (l > 64)
l = 64;
cmd->cmd = CMD_WRITE_BLOCK;
cmd->len = 4 + l;
word_pack(&cmd->args[0], 0x100000 + 0x2000 + dat->off);
memcpy (&cmd->args[4], dat->buf + dat->off, l);
cmd->cb = cb_load;
dat->off += l;
return 1;
}
static void *xmalloc (size_t sz)
{
void *res = malloc (sz);
if (res == NULL) {
fprintf (stderr, "virtual memory exhausted\n");
exit (2);
}
return res;
}
static int cmd_load (const char *filename)
{
FILE *f;
Elf32_Ehdr ehdr;
unsigned poff;
Elf32_Phdr phdr;
struct load_cb_data *data;
unsigned filesz;
unsigned memsz;
struct urv_cmd cmd;
f = fopen (filename, "r");
if (f == NULL) {
fprintf (stderr, "cannot open %s\n", filename);
goto err;
}
if (fread (&ehdr, sizeof (ehdr), 1, f) != 1) {
fprintf (stderr, "cannot read ELF header of %s\n", filename);
goto err;
}
if (ehdr.e_ident[EI_MAG0] != ELFMAG0
|| ehdr.e_ident[EI_MAG1] != ELFMAG1
|| ehdr.e_ident[EI_MAG2] != ELFMAG2
|| ehdr.e_ident[EI_MAG3] != ELFMAG3) {
fprintf (stderr, "file %s is not an ELF file\n", filename);
goto err;
}
if (ehdr.e_ident[EI_CLASS] != ELFCLASS32
|| ehdr.e_ident[EI_DATA] != ELFDATA2LSB
|| ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
fprintf (stderr, "file %s is not expect ELF class\n", filename);
goto err;
}
if (read_elf_half (&ehdr.e_type) != ET_EXEC
|| read_elf_half (&ehdr.e_machine) != 0xf3
|| read_elf_word (&ehdr.e_version) != EV_CURRENT) {
fprintf (stderr, "file %s is not a risc-v executable\n", filename);
goto err;
}
if (read_elf_half (&ehdr.e_phentsize) != sizeof (Elf32_Phdr)
|| read_elf_half (&ehdr.e_phnum) != 2) {
fprintf (stderr, "file %s must have only 2 program entries\n", filename);
goto err;
}
if (read_elf_word (&ehdr.e_entry) != 0) {
fprintf (stderr, "file %s entry point is not 0\n", filename);
goto err;
}
poff = read_elf_word (&ehdr.e_phoff);
if (fseek (f, poff, SEEK_SET) != 0
|| fread (&phdr, sizeof (phdr), 1, f) != 1) {
fprintf (stderr, "%s: cannot read first program header\n", filename);
goto err;
}
if (read_elf_word (&phdr.p_type) != PT_LOAD
|| read_elf_word (&phdr.p_vaddr) != 0) {
fprintf (stderr, "%s: incorrect program header type/address\n", filename);
goto err;
}
data = xmalloc (sizeof (struct load_cb_data));
data->buf = xmalloc (read_elf_word (&phdr.p_memsz));
filesz = read_elf_word (&phdr.p_filesz);
memsz = read_elf_word (&phdr.p_memsz);
memsz = (memsz + 3) & ~3;
if (fseek (f, read_elf_word (&phdr.p_offset), SEEK_SET) != 0
|| fread (data->buf, filesz, 1, f) != 1) {
fprintf (stderr, "%s: cannot read program\n", filename);
goto err;
}
memset (data->buf + filesz, 0, memsz - filesz);
data->off = 0;
data->len = memsz;
/* Check other sections are empty. */
fclose (f);
cmd.cb_data = data;
if (load_cb_prepare(&cmd) == 0)
return 0;
if (append_command(ftb, &cmd) != 0)
return -1;
return 0;
err:
fclose (f);
return -1;
}
/* Return the number of arguments consumed.
0: argument unknown,
< 0: bad argument (error). */
......@@ -447,11 +635,8 @@ static int decode_command (int argc, char *argv[])
cmd.cmd = CMD_READ_WORD;
cmd.len = 4;
cmd.args[0] = val;
cmd.args[1] = val >> 8;
cmd.args[2] = val >> 16;
cmd.args[3] = val >> 24;
cmd.cb = NULL;
word_pack(&cmd.args[0], val);
cmd.cb = cb_read_word;
if (append_command(ftb, &cmd) != 0)
return -1;
......@@ -473,28 +658,33 @@ static int decode_command (int argc, char *argv[])
fprintf (stderr, "incorrect address for write\n");
return -1;
}
val = strtoul (argv[1], &e, 0);
val = strtoul (argv[2], &e, 0);
if (*e != 0) {
fprintf (stderr, "incorrect value for write\n");
return -1;
}
cmd.cmd = CMD_WRITE_WORD;
cmd.len = 4;
cmd.args[0] = addr;
cmd.args[1] = addr >> 8;
cmd.args[2] = addr >> 16;
cmd.args[3] = addr >> 24;
cmd.args[4] = val;
cmd.args[5] = val >> 8;
cmd.args[6] = val >> 16;
cmd.args[7] = val >> 24;
cmd.len = 8;
word_pack(&cmd.args[0], addr);
word_pack(&cmd.args[4], val);
cmd.cb = NULL;
if (append_command(ftb, &cmd) != 0)
return -1;
return 3;
}
else if (strcmp (argv[0], "load") == 0)
{
if (argc < 2) {
fprintf (stderr, "load needs a filename\n");
return -1;
}
if (cmd_load(argv[1]) < 0)
return -1;
return 2;
}
else
return 0;
}
......@@ -530,7 +720,7 @@ int main(int argc, char *argv[])
/* TODO: handle options. */
argc--;
argv++;
while (argc > 0) {
res = decode_command (argc, argv);
if (res == 0) {
......
#define CMD_ERROR 0
#define CMD_SET_LEDS 1
#define CMD_GET_LEDS 2
#define CMD_READ_WORD 3
#define CMD_WRITE_WORD 4
#define CMD_WRITE_WORD 1
#define CMD_READ_WORD 2
#define CMD_WRITE_BLOCK 16
#define CMD_SET_LEDS 3
#define CMD_GET_LEDS 4
......@@ -9,7 +9,7 @@ SIZE = $(CROSS_COMPILE)size
OUTPUT=fip_urv
CFLAGS = -mabi=ilp32 -march=rv32im -O
CFLAGS = -mabi=ilp32 -march=rv32im -Os -Wall
OBJS = crt0.o $(OUTPUT).o
LDS = ram.ld
......@@ -18,7 +18,10 @@ all: $(OUTPUT).ram
fip_urv_regs.h: ../../hdl/rtl/urv_wic/fip_urv_regs.cheby
cheby --gen-c=$@ -i $<
fip_urv.o: fip_urv.c fip_urv_regs.h
mbox_regs.h: ../../hdl/rtl/urv_wic/mbox_regs.cheby
cheby --gen-c=$@ -i $<
fip_urv.o: fip_urv.c fip_urv_regs.h mbox_regs.h fip_urv_cmd.h
%.bin: %.elf
${OBJCOPY} -O binary $< $@
......
......@@ -26,13 +26,12 @@ static void insert_word(unsigned char *buf, unsigned val)
int
main (void)
{
unsigned char leds;
volatile struct fip_urv_regs *regs =
(volatile struct fip_urv_regs *)0x100000;
int j;
unsigned char cmd;
unsigned char reply[8];
unsigned char rdy;
unsigned int leds;
/* Init. */
leds = 1;
......@@ -50,11 +49,11 @@ main (void)
regs->leds = leds;
else
{
regs->leds = (leds << 3) | status;
regs->leds = (leds << 2) | status;
j++;
if (j == 1000000)
{
leds = ((leds << 1) & 0x7) | ((leds >> 2) & 1);
leds = (leds >> 1) | ((leds & 1) << 3);
j = 0;
}
}
......@@ -64,6 +63,7 @@ main (void)
if (status & 1)
{
/* Received. */
unsigned char cmd;
/* Consume variable. */
regs->fip_var1 = 1;
......@@ -75,9 +75,6 @@ main (void)
switch (cmd)
{
case CMD_GET_LEDS:
reply[4] = leds;
break;
case CMD_SET_LEDS:
leds = regs->fip_reg[0x06];
break;
......@@ -89,14 +86,19 @@ main (void)
insert_word(&reply[4], *addr);
}
break;
case CMD_WRITE_BLOCK:
case CMD_WRITE_WORD:
{
unsigned *addr;
unsigned val;
unsigned k;
addr = (unsigned *)extract_word(&regs->fip_reg[0x6]);
val = extract_word(&regs->fip_reg[0xa]);
*addr = val;
for (k = 0; k < cmd; k++)
{
val = extract_word(&regs->fip_reg[0xa + 4*k]);
addr[k] = val;
}
}
break;
default:
......
#define CMD_ERROR 0
#define CMD_SET_LEDS 1
#define CMD_GET_LEDS 2
#define CMD_READ_WORD 3
#define CMD_WRITE_WORD 4
#define CMD_WRITE_WORD 1
#define CMD_READ_WORD 2
#define CMD_WRITE_BLOCK 16
#define CMD_SET_LEDS 3
#define CMD_GET_LEDS 4
#ifndef __CHEBY__FIP_URV_REGS__H__
#define __CHEBY__FIP_URV_REGS__H__
#include "mbox_regs.h"
#define FIP_URV_REGS_SIZE 16384
/* PLC processor control */
#define FIP_URV_REGS_PLC_CTRL 0x0UL
#define FIP_URV_REGS_PLC_CTRL_RST 0x1UL
#define FIP_URV_REGS_PLC_CTRL_RSTN 0x1UL
/* Status bits from NanoFIP */
#define FIP_URV_REGS_FIP_STATUS 0x4UL
......@@ -19,43 +21,47 @@
#define FIP_URV_REGS_FIP_VAR3 0xcUL
#define FIP_URV_REGS_FIP_VAR3_ACC 0x1UL
/* None */
#define FIP_URV_REGS_MAILBOXES 0x10UL
#define FIP_URV_REGS_MAILBOXES_SIZE 16
/* presence lines for boards */
#define FIP_URV_REGS_PRESENCE 0x10UL
#define FIP_URV_REGS_PRESENCE 0x20UL
#define FIP_URV_REGS_PRESENCE_EN_MASK 0xffUL
#define FIP_URV_REGS_PRESENCE_EN_SHIFT 0
/* led */
#define FIP_URV_REGS_LEDS 0x14UL
#define FIP_URV_REGS_LEDS 0x24UL
#define FIP_URV_REGS_LEDS_VAL_MASK 0x3fUL
#define FIP_URV_REGS_LEDS_VAL_SHIFT 0
/* None */
#define FIP_URV_REGS_BOARDS 0x20UL
#define FIP_URV_REGS_BOARDS 0x40UL
#define FIP_URV_REGS_BOARDS_SIZE 32
/* None */
#define FIP_URV_REGS_BOARDS_PINS_0 0x20UL
#define FIP_URV_REGS_BOARDS_PINS_0 0x40UL
/* None */
#define FIP_URV_REGS_BOARDS_PINS_1 0x24UL
#define FIP_URV_REGS_BOARDS_PINS_1 0x44UL
/* None */
#define FIP_URV_REGS_BOARDS_PINS_2 0x28UL
#define FIP_URV_REGS_BOARDS_PINS_2 0x48UL
/* None */
#define FIP_URV_REGS_BOARDS_PINS_3 0x2cUL
#define FIP_URV_REGS_BOARDS_PINS_3 0x4cUL
/* None */
#define FIP_URV_REGS_BOARDS_PINS_4 0x30UL
#define FIP_URV_REGS_BOARDS_PINS_4 0x50UL
/* None */
#define FIP_URV_REGS_BOARDS_PINS_5 0x34UL
#define FIP_URV_REGS_BOARDS_PINS_5 0x54UL
/* None */
#define FIP_URV_REGS_BOARDS_PINS_6 0x38UL
#define FIP_URV_REGS_BOARDS_PINS_6 0x58UL
/* None */
#define FIP_URV_REGS_BOARDS_PINS_7 0x3cUL
#define FIP_URV_REGS_BOARDS_PINS_7 0x5cUL
/* NanoFIP internal memory/registers */
#define FIP_URV_REGS_FIP_REG 0x800UL
......@@ -78,16 +84,22 @@ struct fip_urv_regs {
/* [0xc]: REG (rw) Set access to var 1 */
uint32_t fip_var3;
/* [0x10]: REG (ro) presence lines for boards */
/* [0x10]: SUBMAP (no description) */
struct mbox_regs mailboxes;
/* padding to: 8 words */
uint32_t __padding_0[1];
/* [0x20]: REG (ro) presence lines for boards */
uint32_t presence;
/* [0x14]: REG (rw) led */
/* [0x24]: REG (rw) led */
uint32_t leds;
/* padding to: 8 words */
uint32_t __padding_0[2];
/* padding to: 16 words */
uint32_t __padding_1[6];
/* [0x20]: BLOCK (no description) */
/* [0x40]: BLOCK (no description) */
struct boards {
/* [0x0]: REG (ro) (no description) */
uint32_t pins_0;
......@@ -115,13 +127,13 @@ struct fip_urv_regs {
} boards;
/* padding to: 512 words */
uint32_t __padding_1[496];
uint32_t __padding_2[488];
/* [0x800]: SUBMAP NanoFIP internal memory/registers */
uint32_t fip_reg[512];
/* padding to: 2048 words */
uint32_t __padding_2[1024];
uint32_t __padding_3[1024];
/* [0x2000]: SUBMAP Memory of the PLC urv */
uint32_t plc_mem[2048];
......
......@@ -8,7 +8,7 @@ MEMORY
LENGTH = 1024
bss :
ORIGIN = 0x00010000,
LENGTH = 1024
LENGTH = 2048
/* Sorry, but there is no initialized ram. */
empty :
......@@ -32,7 +32,7 @@ SECTIONS
*(COMMON)
_ebss = .;
. = ALIGN(.);
_fstack = . + 256;
_fstack = . + 1024;
_end = .;
} > bss
}
# and don't touch the rest unless you know what you're doing.
CROSS_COMPILE ?= riscv32-elf-
XCC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
OBJDUMP = $(CROSS_COMPILE)objdump
OBJCOPY = $(CROSS_COMPILE)objcopy
SIZE = $(CROSS_COMPILE)size
PROG=plc_mbox
CFLAGS = -mabi=ilp32 -march=rv32im -Os -Wall
OBJS = crt0.o $(PROG).o
LDS = plc.ld
all: $(PROG).elf
plc_urv_regs.h: ../../hdl/rtl/urv_wic/plc_urv_regs.cheby
cheby --gen-c=$@ -i $<
mbox_regs.h: ../../hdl/rtl/urv_wic/mbox_regs.cheby
cheby --gen-c=$@ -i $<
$(PROG).o: $(PROG).c plc_urv_regs.h mbox_regs.h
$(PROG).elf: $(LDS) $(OBJS)
${XCC} $(CFLAGS) -o $@ -nostartfiles $(OBJS) -T $(LDS) -Wl,-Map=$(PROG).map
$(SIZE) $@
clean:
rm -f $(PROG).elf $(OBJS)
%.o: %.S
${XCC} -c $(CFLAGS) $< -o $@
%.o: %.c
${XCC} -c $(CFLAGS) $< -o $@
.section .boot, "ax", @progbits
.global _start
_start:
la gp, _gp # Initialize global pointer
la sp, _fstack
call init
1: call main
j 1b
#ifndef __CHEBY__MBOX_REGS__H__
#define __CHEBY__MBOX_REGS__H__
#define MBOX_REGS_SIZE 12
/* Mailbox to the fip urv */
#define MBOX_REGS_MBOXOUT 0x0UL
/* Mailbox from the fip urv */
#define MBOX_REGS_MBOXIN 0x4UL
/* Status for mailboxes */
#define MBOX_REGS_STATUS 0x8UL
#define MBOX_REGS_STATUS_MBIN 0x1UL
#define MBOX_REGS_STATUS_MBOUT 0x2UL
struct mbox_regs {
/* [0x0]: REG (wo) Mailbox to the fip urv */
uint32_t mboxout;
/* [0x4]: REG (ro) Mailbox from the fip urv */
uint32_t mboxin;
/* [0x8]: REG (ro) Status for mailboxes */
uint32_t status;
};
#endif /* __CHEBY__MBOX_REGS__H__ */
OUTPUT_FORMAT("elf32-littleriscv")
ENTRY(_start)
MEMORY
{
rom :
ORIGIN = 0x00000000,
LENGTH = 1024
bss :
ORIGIN = 0x00010000,
LENGTH = 2048
/* Sorry, but there is no initialized ram. */
empty :
ORIGIN = 0x00020000,
LENGTH = 0
}
SECTIONS
{
.boot : { *(.boot) } > rom
.text : { *(.text .text.*) } > rom =0
_gp = .;
.rodata : { *(.rodata .rodata.*) } > empty
.data : { *(.data .data.*) } > empty
.bss : {
_fbss = .;
*(.bss .bss.*)
*(COMMON)
_ebss = .;
. = ALIGN(.);
_fstack = . + 1024;
_end = .;
} > bss
}
#include <stdint.h>
#include "plc_urv_regs.h"
#define SLOT pins_4
void
init (void)
{
volatile struct plc_urv_regs *regs =
(volatile struct plc_urv_regs *)0x100000;
regs->relays.SLOT = 0;
}
void
main (void)
{
volatile struct plc_urv_regs *regs =
(volatile struct plc_urv_regs *)0x100000;
unsigned v = regs->loops.SLOT;
regs->relays.SLOT = -(v & 1) & (~1);
}
#include <stdint.h>
#include "plc_urv_regs.h"
void
init (void)
{
volatile struct plc_urv_regs *regs =
(volatile struct plc_urv_regs *)0x100000;
regs->mailboxes.mboxout = 0x12345678;
}
void
main (void)
{
volatile struct plc_urv_regs *regs =
(volatile struct plc_urv_regs *)0x100000;
if (regs->mailboxes.status & MBOX_REGS_STATUS_MBIN)
{
unsigned dat;
dat = regs->mailboxes.mboxin;
regs->mailboxes.mboxout = ~dat;
}
}
#ifndef __CHEBY__PLC_URV_REGS__H__
#define __CHEBY__PLC_URV_REGS__H__
#include "mbox_regs.h"
#define PLC_URV_REGS_SIZE 96
/* None */
#define PLC_URV_REGS_MAILBOXES 0x0UL
#define PLC_URV_REGS_MAILBOXES_SIZE 16
/* presence lines for boards */
#define PLC_URV_REGS_PRESENCE 0x10UL
#define PLC_URV_REGS_PRESENCE_EN_MASK 0xffUL
#define PLC_URV_REGS_PRESENCE_EN_SHIFT 0
/* None */
#define PLC_URV_REGS_LOOPS 0x20UL
#define PLC_URV_REGS_LOOPS_SIZE 32
/* None */
#define PLC_URV_REGS_LOOPS_PINS_0 0x20UL
/* None */
#define PLC_URV_REGS_LOOPS_PINS_1 0x24UL
/* None */
#define PLC_URV_REGS_LOOPS_PINS_2 0x28UL
/* None */
#define PLC_URV_REGS_LOOPS_PINS_3 0x2cUL
/* None */
#define PLC_URV_REGS_LOOPS_PINS_4 0x30UL
/* None */
#define PLC_URV_REGS_LOOPS_PINS_5 0x34UL
/* None */
#define PLC_URV_REGS_LOOPS_PINS_6 0x38UL
/* None */
#define PLC_URV_REGS_LOOPS_PINS_7 0x3cUL
/* None */
#define PLC_URV_REGS_RELAYS 0x40UL
#define PLC_URV_REGS_RELAYS_SIZE 32
/* None */
#define PLC_URV_REGS_RELAYS_PINS_0 0x40UL
/* None */
#define PLC_URV_REGS_RELAYS_PINS_1 0x44UL
/* None */
#define PLC_URV_REGS_RELAYS_PINS_2 0x48UL
/* None */
#define PLC_URV_REGS_RELAYS_PINS_3 0x4cUL
/* None */
#define PLC_URV_REGS_RELAYS_PINS_4 0x50UL
/* None */
#define PLC_URV_REGS_RELAYS_PINS_5 0x54UL
/* None */
#define PLC_URV_REGS_RELAYS_PINS_6 0x58UL
/* None */
#define PLC_URV_REGS_RELAYS_PINS_7 0x5cUL
struct plc_urv_regs {
/* [0x0]: SUBMAP (no description) */
struct mbox_regs mailboxes;
/* padding to: 4 words */
uint32_t __padding_0[1];
/* [0x10]: REG (ro) presence lines for boards */
uint32_t presence;
/* padding to: 8 words */
uint32_t __padding_1[3];
/* [0x20]: BLOCK (no description) */
struct loops {
/* [0x0]: REG (ro) (no description) */
uint32_t pins_0;
/* [0x4]: REG (ro) (no description) */
uint32_t pins_1;
/* [0x8]: REG (ro) (no description) */
uint32_t pins_2;
/* [0xc]: REG (ro) (no description) */
uint32_t pins_3;
/* [0x10]: REG (ro) (no description) */
uint32_t pins_4;
/* [0x14]: REG (ro) (no description) */
uint32_t pins_5;
/* [0x18]: REG (ro) (no description) */
uint32_t pins_6;
/* [0x1c]: REG (ro) (no description) */
uint32_t pins_7;
} loops;
/* [0x40]: BLOCK (no description) */
struct relays {
/* [0x0]: REG (rw) (no description) */
uint32_t pins_0;
/* [0x4]: REG (rw) (no description) */
uint32_t pins_1;
/* [0x8]: REG (rw) (no description) */
uint32_t pins_2;
/* [0xc]: REG (rw) (no description) */
uint32_t pins_3;
/* [0x10]: REG (rw) (no description) */
uint32_t pins_4;
/* [0x14]: REG (rw) (no description) */
uint32_t pins_5;
/* [0x18]: REG (rw) (no description) */
uint32_t pins_6;
/* [0x1c]: REG (rw) (no description) */
uint32_t pins_7;
} relays;
};
#endif /* __CHEBY__PLC_URV_REGS__H__ */
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