Commit 0144fd39 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

Support for embedded interrupt controller added

parent ed76e70f
SOURCES = cgen_c_headers.lua cgen_common.lua cgen_verilog.lua cgen_vhdl.lua target_wishbone.lua wbgen_common.lua wbgen_main.lua wbgen_rams.lua wbgen_regbank.lua wbgen_eic.lua
OUTPUT = wbgen2
all: $(SOURCES)
./utils/process_dofiles.lua wbgen_main.lua wbgen2
chmod +x wbgen2
\ No newline at end of file
......@@ -3,5 +3,4 @@ This is the initial version of wbgen2. Requires Lua 5.1.4+. Enjoy it :)
There is still some stuff to do:
- add FIFOs
- add documentation generator
- CONSTANT registers
- add EIC
\ No newline at end of file
- CONSTANT registers
\ No newline at end of file
......@@ -56,15 +56,17 @@ end
-- iterates all regs and rams and generates appropriate #define-s
function cgen_c_field_masks()
foreach_reg(function(reg)
if(reg.__type == TYPE_REG and reg.num_fields ~= nil and reg.num_fields > 0) then
foreach_reg({TYPE_REG}, function(reg)
if(reg.num_fields ~= nil and reg.num_fields > 0) then
emit("");
emit("/* definitions for register: "..reg.name.." */");
foreach_subfield(reg, function(field, reg) cgen_c_field_define(field, reg) end);
elseif (reg.__type == TYPE_RAM) then
cgen_c_ramdefs(reg);
end
end);
foreach_reg({TYPE_RAM}, function(ram)
cgen_c_ramdefs(ram);
end);
end
......@@ -126,20 +128,18 @@ function cgen_c_struct()
-- emit struct entires for REGs
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
pad_struct(reg.base);
emit(string.format("/* [0x%x]: REG "..reg.name.." */", reg.base * DATA_BUS_WIDTH / 8));
foreach_reg({TYPE_REG}, function(reg)
-- print(reg.name, reg.prefix, reg.c_prefix, reg.hdl_prefix);
pad_struct(reg.base);
emit(string.format("/* [0x%x]: REG "..reg.name.." */", reg.base * DATA_BUS_WIDTH / 8));
-- this is just simple :)
emit("uint32_t "..string.upper(reg.prefix)..";");
cur_offset = cur_offset + 1;
end
emit("uint32_t "..string.upper(reg.c_prefix)..";");
cur_offset = cur_offset + 1;
end);
-- .. and for RAMs
foreach_reg(function(ram)
if(ram.__type == TYPE_RAM) then
foreach_reg({TYPE_RAM}, function(ram)
-- calculate base address of the RAM
......@@ -161,11 +161,10 @@ function cgen_c_struct()
-- and the RAM, as an array
if(ram.byte_select) then
emit("uint8_t "..string.upper(ram.prefix).." ["..(ram.size * (DATA_BUS_WIDTH/8) * math.pow(2, ram.wrap_bits)) .."];");
emit("uint8_t "..string.upper(ram.c_prefix).." ["..(ram.size * (DATA_BUS_WIDTH/8) * math.pow(2, ram.wrap_bits)) .."];");
else
emit("uint32_t "..string.upper(ram.prefix).." ["..(ram.size * math.pow(2, ram.wrap_bits)) .."];");
emit("uint32_t "..string.upper(ram.c_prefix).." ["..(ram.size * math.pow(2, ram.wrap_bits)) .."];");
end
end
end);
indent_left();
......
......@@ -330,18 +330,17 @@ function cgen_gen_vlog_constants(filename)
die("can't open "..filename.." for writing.");
end
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
file.write(file, string.format("`define %-30s %d'h%x\n", "ADDR_"..string.upper(periph.hdl_prefix.."_"..reg.hdl_prefix), address_bus_width, (DATA_BUS_WIDTH/8) * reg.base));
end
if(reg.__type == TYPE_RAM) then
foreach_reg({TYPE_REG}, function(reg)
file.write(file, string.format("`define %-30s %d'h%x\n", "ADDR_"..string.upper(periph.hdl_prefix.."_"..reg.hdl_prefix), address_bus_width+2, (DATA_BUS_WIDTH/8) * reg.base));
end);
foreach_reg({TYPE_RAM}, function(reg)
local base = reg.select_bits *
math.pow (2, address_bus_width - address_bus_select_bits);
file.write(file, string.format("`define %-30s %d'h%x\n", "BASE_"..string.upper(periph.hdl_prefix.."_"..reg.hdl_prefix), address_bus_width+2, (DATA_BUS_WIDTH/8) *base));
file.write(file, string.format("`define %-30s 32'h%x\n", "SIZE_"..string.upper(periph.hdl_prefix.."_"..reg.hdl_prefix), reg.size));
end
end
);
end);
io.close(file);
end
#!/usr/bin/lua
-- -*- Mode: LUA; tab-width: 2 -*-
-- wbgen2, (c) 2010 Tomasz Wlostowski/CERN BE-Co-HT
-- LICENSED UNDER GPL v2
......@@ -54,7 +54,7 @@ function cgen_vhdl_header()
emit("use ieee.numeric_std.all;");
-- do we have RAMs or FIFOs? - if yes, include the wbgen2 components library.
if(periph.ramcount > 0 or periph.fifocount > 0 ) then
if(periph.ramcount > 0 or periph.fifocount > 0 or periph.irqcount > 0) then
emit("library wbgen2;");
emit("use wbgen2.wbgen2_pkg.all;");
end
......
-------------------------------------------------------------------------------
-- Title : A sample GPIO port (wbgen2 example)
-- Project :
-------------------------------------------------------------------------------
-- File : gpio_port.vhdl
-- Author : T.W.
-- Company :
-- Created : 2010-02-22
-- Last update: 2010-03-15
-- Platform :
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2010 T.W.
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-02-22 1.0 slayer Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
entity gpio_port is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
-- our port :)
gpio_pins_b : inout std_logic_vector(31 downto 0)
);
end gpio_port;
architecture syn of gpio_port is
component wb_slave_gpio_port
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(2 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
gpio_ddr_o : out std_logic_vector(31 downto 0);
gpio_psr_i : in std_logic_vector(31 downto 0);
gpio_pdr_o : out std_logic_vector(31 downto 0);
gpio_pdr_wr_o : out std_logic;
gpio_sopr_o : out std_logic_vector(31 downto 0);
gpio_sopr_wr_o : out std_logic;
gpio_copr_o : out std_logic_vector(31 downto 0);
gpio_copr_wr_o : out std_logic);
end component;
signal gpio_ddr : std_logic_vector(31 downto 0);
signal gpio_psr : std_logic_vector(31 downto 0);
signal gpio_pdr : std_logic_vector(31 downto 0);
signal gpio_pdr_wr : std_logic;
signal gpio_sopr : std_logic_vector(31 downto 0);
signal gpio_sopr_wr : std_logic;
signal gpio_copr : std_logic_vector(31 downto 0);
signal gpio_copr_wr : std_logic;
-- regsiter containing current output state
signal gpio_reg : std_logic_vector(31 downto 0);
-- registers for synchronization of input pins
signal gpio_pins_sync1 : std_logic_vector(31 downto 0);
signal gpio_pins_sync0 : std_logic_vector(31 downto 0);
begin -- syn
wb_slave : wb_slave_gpio_port
port map (
rst_n_i => rst_n_i,
wb_clk_i => wb_clk_i,
wb_addr_i => wb_addr_i,
wb_data_i => wb_data_i,
wb_data_o => wb_data_o,
wb_cyc_i => wb_cyc_i,
wb_sel_i => wb_sel_i,
wb_stb_i => wb_stb_i,
wb_we_i => wb_we_i,
wb_ack_o => wb_ack_o,
gpio_ddr_o => gpio_ddr,
gpio_psr_i => gpio_pins_sync1,
gpio_pdr_o => gpio_pdr,
gpio_pdr_wr_o => gpio_pdr_wr,
gpio_sopr_o => gpio_sopr,
gpio_sopr_wr_o => gpio_sopr_wr,
gpio_copr_o => gpio_copr,
gpio_copr_wr_o => gpio_copr_wr);
process (wb_clk_i, rst_n_i)
begin -- process
if(rst_n_i = '0') then
gpio_reg <= (others => '0');
elsif rising_edge(wb_clk_i) then
if(gpio_pdr_wr = '1') then -- write operation to "PDR" register -
-- set the new values of GPIO outputs
gpio_reg <= gpio_pdr;
end if;
if(gpio_sopr_wr = '1') then -- write to "SOPR" reg - set ones
for i in 0 to 31 loop
if(gpio_sopr(i) = '1') then
gpio_reg(i) <= '1';
end if;
end loop;
end if;
if(gpio_copr_wr = '1') then -- write to "COPR" reg - set zeros
for i in 0 to 31 loop
if(gpio_copr(i) = '1') then
gpio_reg(i) <= '0';
end if;
end loop;
end if;
end if;
end process;
-- synchronizing process for input pins
synchronize_input_pins : process (wb_clk_i, rst_n_i)
begin -- process
if(rst_n_i = '0') then
gpio_pins_sync0 <= (others => '0');
gpio_pins_sync1 <= (others => '0');
elsif rising_edge(wb_clk_i) then
gpio_pins_sync0 <= gpio_pins_b;
gpio_pins_sync1 <= gpio_pins_sync0;
end if;
end process;
-- generate the tristate buffers for I/O pins
gen_tristates : for i in 0 to 31 generate
gpio_pins_b(i) <= gpio_reg(i) when gpio_ddr(i) = '1' else 'Z';
end generate gen_tristates;
end syn;
-- here comes our peripheral definition
peripheral {
-- short (human-readable) name for the peripheral.
name = "GPIO Port";
-- a longer description, if you want
description = "A sample 32-bit general-purpose bidirectional I/O port, explaining how to use SLV and PASS-THROUGH registers.";
-- name of the target VHDL entity to be generated
hdl_entity = "wb_slave_gpio_port";
-- prefix for all the generated ports belonging to our peripheral
prefix = "gpio";
-- Pin direction register. Readable and writable from the bus, readable from the device.
reg {
name = "Pin direction register";
description = "A register defining the direction of the GPIO potr pins.";
prefix = "ddr";
-- a single, anonymous field (no prefix) of type SLV.
field {
name = "Pin directions";
description = "Each bit in this register defines the direction of corresponding pin of the GPIO port. 1 means the pin is an OUTPUT, 0 means the pin is an INPUT";
-- there is (deliberately) no prefix defined for this field. Since we have only one field in the register "ddr", we can omit the prefix - wbgen2 will produce signal names
-- containing only prefixes of the peripheral and the parent register.
-- type of our field - std_logic_vector
type = SLV;
-- size - we want 32-bits wide port :)
size = 32;
-- the field will be readable/writable from the Wishbone bus
access_bus = READ_WRITE;
-- .. and readable from the peripheral
access_dev = READ_ONLY;
};
};
-- Pin input state register. Readable the bus, writable from the device.
reg {
name = "Pin input state register";
description = "A register containing the current state of input pins.";
prefix = "psr";
-- a single, anonymous field (no prefix) of type SLV.
field {
name = "Pin input state";
description = "Each bit in this register reflects the state of corresponding GPIO port pin.";
-- no prefix here as well (see above)
-- type of our field - std_logic_vector
type = SLV;
-- size - we want 32-bits wide port :)
size = 32;
-- the field will be readable from the Wishbone bus
access_bus = READ_ONLY;
-- .. and writable from the peripheral
access_dev = WRITE_ONLY;
};
};
-- Port output register. Shows how to use PASS-THROUGH regs
reg {
name = "Port output register";
description = "Register containing the output pin state.";
prefix = "pdr";
-- a single, anonymous field (no prefix) of type PASS-THROUGH.
field {
name = "Port output value";
-- the description isn't really necessary here :)
-- description = "Writing '1' sets the corresponding GPIO pin to '1'";
-- type of our field - PASS_THROUGH. In this mode, the slave core is not storing the register value. Instead it provides the raw value
-- (taken from the wishbone data input) and a strobe signal, asserted for single clock cycle upon write operation to the register.
-- The wishbone data input will be fed directly to gpio_pdr_o and each write operation to this register will generate a single-cycle positive
-- pulse on gpio_pdr_wr_o signal.
type = PASS_THROUGH;
size = 32;
-- access flags don't apply for the PASS-THROUGH regsiters, so we can omit them.
};
};
-- Set output register. Shows how to use PASS-THROUGH regs
reg {
name = "Set output pin register";
description = "Writing '1' sets the corresponding GPIO pin to '1'";
prefix = "sopr";
-- Our driver developer would want these two (SOPR and COPR) registers' addresses to be aligned to multiple of 4 :)
align = 4;
field {
name = "Set output pin register";
type = PASS_THROUGH;
size = 32;
};
};
-- Clear output register. Designed identically as the previous reg.
reg {
name = "Clear output pin register";
description = "Writing '1' clears the corresponding GPIO pin";
prefix = "copr";
field {
name = "Clear output pin register";
type = PASS_THROUGH;
size = 32;
};
};
};
This diff is collapsed.
vlib work
vlib wbgen2
../../wbgen2.lua rams.wb -vo ./output/wb_slave_test_rams.vhdl -consto ./output/vlog_constants.v
../../wbgen2 rams.wb -vo ./output/wb_test_interrupts.vhd -consto ./output/vlog_constants.v -co ./output/test_interrupts.h
vcom -work work ./output/wb_slave_test_rams.vhdl
vcom -work wbgen2 ../../lib/wbgen2_pkg.vhd
vcom -work wbgen2 ../../lib/wbgen2_dpssram.vhd
vcom -work wbgen2 ../../lib/wbgen2_eic.vhd
vcom -work work ./output/wb_test_interrupts.vhd
vlog ./testbench.v
......@@ -13,6 +13,6 @@ vsim work.main
radix -hexadecimal
do wave.do
run 15us
run 1000us
wave zoomfull
m255
13
cModel Technology
d/home/slayer/wbgen2_svn/wbgen2/examples/RAMs
Ewbgen2_dpssram
w1269003774
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
F../../lib/wbgen2_dpssram.vhd
l0
L11
V^GZe>D]^?P9JVgYAAikm:3
OE;C;6.2b;35
32
o-work wbgen2
tExplicit 1
Asyn
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DE work wbgen2_dpssram ^GZe>D]^?P9JVgYAAikm:3
l99
L46
VZD:]3B@TAeo`KW[NHAIkP0
OE;C;6.2b;35
32
M1 ieee std_logic_1164
o-work wbgen2
tExplicit 1
Pwbgen2_pkg
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
w1268907251
F../../lib/wbgen2_pkg.vhd
l0
L6
VO41XCVO6fF0I4?bScoJKd3
OE;C;6.2b;35
32
M1 ieee std_logic_1164
o-work wbgen2
tExplicit 1
m255
13
cModel Technology
d/home/slayer/wbgen2_svn/wbgen2/examples/RAMs
T_opt
o-quiet +acc -auto_acc_if_foreign -work work
tExplicit 1
OE;O;6.2b;35
T_opt1
VA:`f030HMAPjdST`l7eQQ2
04 4 4 work main fast 0
o-quiet +acc -auto_acc_if_foreign -work work
tExplicit 1
OE;O;6.2b;35
T_opt2
o-quiet +acc -auto_acc_if_foreign -work work
tExplicit 1
OE;O;6.2b;35
Egpio_port
w1268865151
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
F./gpio_port.vhdl
l0
L27
V=48Cd@cI0EFDRnHinnSkI2
OE;C;6.2b;35
32
tExplicit 1
Asyn
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DE work gpio_port =48Cd@cI0EFDRnHinnSkI2
l86
L46
VE9ChVMG=a34IjH39JN^@>2
OE;C;6.2b;35
32
M1 ieee std_logic_1164
tExplicit 1
vmain
IgRg>D1noQ7dH21j:7TPk12
VEAT@0_d?1jQUQ5cgEJon`1
w1269015033
F./testbench.v
Foutput/vlog_constants.v
Fwishbone_stuff.v
L0 8
VEAT@0_d?1jQUQ5cgEJon`1
OE;L;6.2b;35
r1
31
Ewb_slave_gpio_port
w1268867801
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
F./output/wb_slave_gpio_port.vhdl
l0
L17
VjCZBzXQYDT`TMj1DM8gO;0
OE;C;6.2b;35
32
tExplicit 1
Asyn
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DE work wb_slave_gpio_port jCZBzXQYDT`TMj1DM8gO;0
l60
L45
VN=Coe86jG20]Cd<;BBnLC1
OE;C;6.2b;35
32
M2 ieee std_logic_1164
M1 ieee numeric_std
tExplicit 1
Ewb_slave_test_rams
w1269015033
DP wbgen2 wbgen2_pkg O41XCVO6fF0I4?bScoJKd3
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
F./output/wb_slave_test_rams.vhdl
l0
L19
VhQNYdf_X>K:Gz6`0m;=G=2
OE;C;6.2b;35
32
o-work work
tExplicit 1
Asyn
DP wbgen2 wbgen2_pkg O41XCVO6fF0I4?bScoJKd3
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DE work wb_slave_test_rams hQNYdf_X>K:Gz6`0m;=G=2
l73
L53
V_1C5NMmc]ZDzB^ZZSV72o2
OE;C;6.2b;35
32
M3 ieee std_logic_1164
M2 ieee numeric_std
M1 wbgen2 wbgen2_pkg
o-work work
tExplicit 1
m255
cModel Technology Builtin Library
13
dD:\qa\patch6_2\nightly\master\modeltech
Pmath_complex
DP work math_real zjAF7SKfg_RPI0GT^n1N`1
OL;C;6.2b;35
31
b1
M1 work math_real
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/ieee/1076-2code.vhd
l0
L687
V1a;R8Z_kc3Q7^>9;gKVIV0
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/1076-2code.vhd
tExplicit 1
Bbody
DB work math_complex 1a;R8Z_kc3Q7^>9;gKVIV0
DP work math_real zjAF7SKfg_RPI0GT^n1N`1
OL;C;6.2b;35
31
M1 work math_real
OP;C;6.2b;35
l0
L687
VIMmI^hXJEW@Uoa4kJFX:K1
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/1076-2code.vhd
tExplicit 1
nbody
Pmath_real
OL;C;6.2b;35
31
b1
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/ieee/1076-2code.vhd
l0
L55
VzjAF7SKfg_RPI0GT^n1N`1
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/1076-2code.vhd
tExplicit 1
Bbody
DB work math_real zjAF7SKfg_RPI0GT^n1N`1
OL;C;6.2b;35
31
OP;C;6.2b;35
l0
L55
V:TOmE?QHig?1Xi[gFIA[l1
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/1076-2code.vhd
tExplicit 1
nbody
Pnumeric_bit
OL;C;6.2b;35
31
b1
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/ieee/mti_numeric_bit.vhd
l0
L58
VK1ChclJ;R]bj:<QN8`za13
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/mti_numeric_bit.vhd -nowarn 3
tExplicit 1
Bbody
DB work numeric_bit K1ChclJ;R]bj:<QN8`za13
OL;C;6.2b;35
31
OP;C;6.2b;35
l0
L58
VMl`J4ca2be3ejNXY`>k4Y1
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/mti_numeric_bit.vhd -nowarn 3
tExplicit 1
nbody
Pnumeric_std
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
b1
M1 ieee std_logic_1164
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/ieee/mti_numeric_std.vhd
l0
L57
V=NSdli^?T5OD8;4F<blj<3
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/mti_numeric_std.vhd -nowarn 3
tExplicit 1
Bbody
DB work numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
M1 ieee std_logic_1164
OP;C;6.2b;35
l0
L57
V;m@IM<mVXokEM:EdoJkM40
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/mti_numeric_std.vhd -nowarn 3
tExplicit 1
nbody
Pstd_logic_1164
OL;C;6.2b;35
31
b1
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/ieee/stdlogic.vhd
l0
L36
VGH1=`jDDBJ=`LM;:Ak`kf2
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/stdlogic.vhd
tExplicit 1
Bbody
DB work std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
OP;C;6.2b;35
l0
L36
V?YNEkS<^lY?<6LBZLFa8D0
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/ieee/stdlogic.vhd
tExplicit 1
nbody
Pstd_logic_arith
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
b1
M1 ieee std_logic_1164
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_arith.vhd
l0
L25
VGJbAT?7@hRQU9IQ702DT]2
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_arith.vhd
tExplicit 1
Bbody
DB work std_logic_arith GJbAT?7@hRQU9IQ702DT]2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
M1 ieee std_logic_1164
OP;C;6.2b;35
l0
L25
VWh`K2GRna_=ITGj@XNmX80
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_arith.vhd
tExplicit 1
nbody
Pstd_logic_misc
DP synopsys attributes oP@SNI848YZ9iazan5Mg_2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
b1
M2 ieee std_logic_1164
M1 synopsys attributes
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_misc.vhd
l0
L24
VD2f;@P3IKJA9T^H8HI[9K0
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_misc.vhd
tExplicit 1
Bbody
DB work std_logic_misc D2f;@P3IKJA9T^H8HI[9K0
DP synopsys attributes oP@SNI848YZ9iazan5Mg_2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
M2 ieee std_logic_1164
M1 synopsys attributes
OP;C;6.2b;35
l0
L24
V>2Z50F2Um7SR`gOQH`oSK0
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_misc.vhd
tExplicit 1
nbody
Pstd_logic_signed
DP ieee std_logic_arith GJbAT?7@hRQU9IQ702DT]2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
b1
M2 ieee std_logic_1164
M1 ieee std_logic_arith
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_signed.vhd
l0
L35
V<9<Kcl:S52:oW`F]FQhb20
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_signed.vhd
tExplicit 1
Bbody
DB work std_logic_signed <9<Kcl:S52:oW`F]FQhb20
DP ieee std_logic_arith GJbAT?7@hRQU9IQ702DT]2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
M2 ieee std_logic_1164
M1 ieee std_logic_arith
OP;C;6.2b;35
l0
L35
VDR>6>65S7FR:e[I>ADUQO1
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_signed.vhd
tExplicit 1
nbody
Pstd_logic_textio
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DP std textio K]Z^fghZ6B=BjnK5NomDT3
OL;C;6.2b;35
31
b1
M2 std textio
M1 ieee std_logic_1164
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/synopsys/std_logic_textio.vhd
l0
L22
V8YS?iX`WD1REQG`ZRYQGB2
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/std_logic_textio.vhd
tExplicit 1
Bbody
DB work std_logic_textio 8YS?iX`WD1REQG`ZRYQGB2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DP std textio K]Z^fghZ6B=BjnK5NomDT3
OL;C;6.2b;35
31
M2 std textio
M1 ieee std_logic_1164
OP;C;6.2b;35
l0
L22
Vj9DSczGXI>dbiF;m2[GMa2
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/std_logic_textio.vhd
tExplicit 1
nbody
Pstd_logic_unsigned
DP ieee std_logic_arith GJbAT?7@hRQU9IQ702DT]2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
b1
M2 ieee std_logic_1164
M1 ieee std_logic_arith
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_unsigned.vhd
l0
L34
VhEMVMlaNCR^<OOoVNV;m90
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_unsigned.vhd
tExplicit 1
Bbody
DB work std_logic_unsigned hEMVMlaNCR^<OOoVNV;m90
DP ieee std_logic_arith GJbAT?7@hRQU9IQ702DT]2
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
31
M2 ieee std_logic_1164
M1 ieee std_logic_arith
OP;C;6.2b;35
l0
L34
V1=Y]oOSl8JChnzj5R39ha2
OE;C;6.2b;35
o-93 -work ieee -path $MODEL_TECH/../vhdl_src/synopsys/mti_std_logic_unsigned.vhd
tExplicit 1
nbody
Pvital_primitives
DP ieee vital_timing OBWK>;kUYmkG<OChK2lhV1
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
30
b1
M2 ieee std_logic_1164
M1 ieee vital_timing
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/vital95/prmtvs_p.vhd
l0
L47
VE9g6AWKAc2T]enMfl94If3
OE;C;6.2b;35
o-87 -novital -novital -work ieee -path $MODEL_TECH/../vhdl_src/vital95/prmtvs_p.vhd
tExplicit 1
Bbody
DB work vital_primitives E9g6AWKAc2T]enMfl94If3
DP std textio K]Z^fghZ6B=BjnK5NomDT3
DP ieee vital_timing OBWK>;kUYmkG<OChK2lhV1
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
30
M3 ieee std_logic_1164
M2 ieee vital_timing
M1 std textio
OP;C;6.2b;35
F$MODEL_TECH/../vhdl_src/vital95/prmtvs_b.vhd
l0
L47
V>[EMmIIzoCHn?@614I_=a3
OE;C;6.2b;35
o-87 -novital -novital -work ieee -path $MODEL_TECH/../vhdl_src/vital95/prmtvs_b.vhd
tExplicit 1
nbody
Pvital_timing
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
30
b1
M1 ieee std_logic_1164
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/vital95/timing_p.vhd
l0
L46
VOBWK>;kUYmkG<OChK2lhV1
OE;C;6.2b;35
o-87 -novital -novital -work ieee -path $MODEL_TECH/../vhdl_src/vital95/timing_p.vhd
tExplicit 1
Bbody
DB work vital_timing OBWK>;kUYmkG<OChK2lhV1
DP std textio K]Z^fghZ6B=BjnK5NomDT3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
OL;C;6.2b;35
30
M2 ieee std_logic_1164
M1 std textio
OP;C;6.2b;35
F$MODEL_TECH/../vhdl_src/vital95/timing_b.vhd
l0
L46
VfN[Pf:HE;^Z^LCeH6gGI81
OE;C;6.2b;35
o-87 -novital -novital -work ieee -path $MODEL_TECH/../vhdl_src/vital95/timing_b.vhd
tExplicit 1
nbody
m255
cModel Technology Builtin Library
13
dD:\qa\patch6_2\nightly\master\modeltech
Pstandard
OL;C;6.2b;35
31
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/std/standard.vhd
l0
L8
V9SL6g`:IK^4S07MiOU]DY2
OE;C;6.2b;35
o-s -93 -work std -path $MODEL_TECH/../vhdl_src/std/standard.vhd
tExplicit 1
Ptextio
OL;C;6.2b;35
31
b1
OP;C;6.2b;35
d.
F$MODEL_TECH/../vhdl_src/std/textio.vhd
l0
L11
VK]Z^fghZ6B=BjnK5NomDT3
OE;C;6.2b;35
o-93 -work std -path $MODEL_TECH/../vhdl_src/std/textio.vhd
tExplicit 1
Bbody
DB work textio K]Z^fghZ6B=BjnK5NomDT3
OL;C;6.2b;35
31
OP;C;6.2b;35
l0
L11
V<aSA_n5_Z?BQ97PO]oKmn2
OE;C;6.2b;35
o-93 -work std -path $MODEL_TECH/../vhdl_src/std/textio.vhd
tExplicit 1
nbody
H 2141964 10 3 0 3 2 0 0 0 0
L 4 ieee 19 $MODEL_TECH/../ieee
L 3 std 18 $MODEL_TECH/../std
L 4 work 4 work
D 19 work.gpio_port(syn) E9ChVMG=a34IjH39JN^@>2 1 1
D 9 work.main OT`WFa]ZX5_Ob[Mb8Clm33 2 0
D 28 work.wb_slave_gpio_port(syn) N=Coe86jG20]Cd<;BBnLC1 0 1
2 0 0 4R35zeN1:dQH=0e^;9PT:2 0 0 1
2 4 fast 0 H7QnTAo`W3H:Ti041l:DH1 1 2 1
m255
13
cModel Technology
d/home/slayer/wbgen2_svn/wbgen2/examples/RAMs
T_opt
o-quiet +acc -auto_acc_if_foreign -work work
tExplicit 1
OE;O;6.2b;35
T_opt1
o-quiet +acc -auto_acc_if_foreign -work work
tExplicit 1
OE;O;6.2b;35
T_opt2
o-quiet +acc -auto_acc_if_foreign -work work
tExplicit 1
OE;O;6.2b;35
Egpio_port
w1268865151
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
F./gpio_port.vhdl
l0
L27
V=48Cd@cI0EFDRnHinnSkI2
OE;C;6.2b;35
32
tExplicit 1
Asyn
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DE work gpio_port =48Cd@cI0EFDRnHinnSkI2
l86
L46
VE9ChVMG=a34IjH39JN^@>2
OE;C;6.2b;35
32
M1 ieee std_logic_1164
tExplicit 1
vmain
IJ];cmm_je45gB057SFl7E0
VEAT@0_d?1jQUQ5cgEJon`1
w1268907328
F./testbench.v
Foutput/vlog_constants.v
Fwishbone_stuff.v
L0 8
VEAT@0_d?1jQUQ5cgEJon`1
OE;L;6.2b;35
r1
31
Ewb_slave_gpio_port
w1268867801
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
F./output/wb_slave_gpio_port.vhdl
l0
L17
VjCZBzXQYDT`TMj1DM8gO;0
OE;C;6.2b;35
32
tExplicit 1
Asyn
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DE work wb_slave_gpio_port jCZBzXQYDT`TMj1DM8gO;0
l60
L45
VN=Coe86jG20]Cd<;BBnLC1
OE;C;6.2b;35
32
M2 ieee std_logic_1164
M1 ieee numeric_std
tExplicit 1
Ewb_slave_test_rams
w1268907328
DP wbgen2 wbgen2_pkg O41XCVO6fF0I4?bScoJKd3
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
F./output/wb_slave_test_rams.vhdl
l0
L19
VhQNYdf_X>K:Gz6`0m;=G=2
OE;C;6.2b;35
32
o-work work
tExplicit 1
Asyn
DP wbgen2 wbgen2_pkg O41XCVO6fF0I4?bScoJKd3
DP ieee numeric_std =NSdli^?T5OD8;4F<blj<3
DP ieee std_logic_1164 GH1=`jDDBJ=`LM;:Ak`kf2
DE work wb_slave_test_rams hQNYdf_X>K:Gz6`0m;=G=2
l73
L53
V_1630@AdY0_LcU47bLKNL3
OE;C;6.2b;35
32
M3 ieee std_logic_1164
M2 ieee numeric_std
M1 wbgen2 wbgen2_pkg
o-work work
tExplicit 1
library verilog;
use verilog.vl_types.all;
entity main is
end main;
`define ADDR_GPIO_DDR 3'h0
`define ADDR_GPIO_PSR 3'h1
`define ADDR_GPIO_PDR 3'h2
`define ADDR_GPIO_SOPR 3'h4
`define ADDR_GPIO_COPR 3'h5
`define ADDR_GPIO_DDR 3'h0
`define ADDR_GPIO_PSR 3'h1
`define ADDR_GPIO_PDR 3'h2
`define ADDR_GPIO_SOPR 3'h4
`define ADDR_GPIO_COPR 3'h5
......@@ -772,7 +772,9 @@ libhm = $MODEL_TECH/libhm.sl
Project_Version = 6
Project_DefaultLib = work
Project_SortMethod = unused
Project_Files_Count = 0
Project_Files_Count = 1
Project_File_0 = /home/slayer/wbgen2_svn/wbgen2/examples/interrupts/testbench.v
Project_File_P_0 = cover_toggle 0 vlog_protect 0 file_type verilog group_id 0 cover_exttoggle 0 cover_cond 0 vlog_nodebug 0 vlog_1995compat 0 vlog_noload 0 folder {Top Level} last_compile 0 cover_fsm 0 cover_branch 0 vlog_enable0In 0 vlog_disableopt 0 vlog_vopt 1 vlog_showsource 0 vlog_hazard 0 vlog_0InOptions {} ood 1 vlog_upper 0 compile_to work vlog_options {} compile_order 0 cover_expr 0 dont_compile 0 cover_stmt 0
Project_Sim_Count = 0
Project_Folder_Count = 0
Echo_Compile_Output = 0
......@@ -802,6 +804,6 @@ XML_DoubleClick = Edit
XML_CustomDoubleClick =
LOGFILE_DoubleClick = Edit
LOGFILE_CustomDoubleClick =
EditorState = {tabbed horizontal 1} {/home/slayer/TWVGA/core_verilog/run.do 0 0} {/home/slayer/TWVGA/core_verilog/testbench-uart.v 0 0}
EditorState = {tabbed horizontal 1} {/home/slayer/wbgen2_svn/wbgen2/examples/interrupts/run.do 0 0}
Project_Major_Version = 6
Project_Minor_Version = 2
-- here comes our peripheral definition
peripheral {
-- short (human-readable) name for the peripheral.
name = "Test IRQs";
-- a longer description, if you want
description = "Embedded interrupt controller test.";
-- name of the target VHDL entity to be generated
hdl_entity = "wb_test_interrupts";
-- prefix for all the generated ports belonging to our peripheral
prefix = "TESTIRQ";
irq {
name = "Edge-positive";
prefix = "ipe";
trigger = EDGE_RISING;
};
irq {
name = "Edge-negative";
prefix = "ine";
trigger = EDGE_FALLING;
};
irq {
name = "Level-0";
prefix = "il0";
trigger = LEVEL_0;
};
irq {
name = "Level-1";
prefix = "il1";
trigger = LEVEL_1;
};
};
vlib work
vlib wbgen2
../../wbgen2 interrupts.wb -vo ./output/wb_test_interrupts.vhd -consto ./output/vlog_constants.v -co ./output/test_interupts.h
vcom -work wbgen2 ../../lib/wbgen2_pkg.vhd
vcom -work wbgen2 ../../lib/wbgen2_eic.vhd
vcom -work work ./output/wb_test_interrupts.vhd
vlog ./testbench.v
vsim work.main
radix -hexadecimal
do wave.do
run 50us
wave zoomfull
`timescale 1ns/1ps
`define wbclk_period 100
`define async_clk_period 63
`include "output/vlog_constants.v"
module main;
reg clk=1;
reg ram1_clk = 1;
reg [31:0] rval;
reg rst=0;
// generate clocks & reset
always #(`wbclk_period/2) clk <= ~clk;
initial #1000 rst <= 1;
`include "wishbone_stuff.v"
function [4:0] decode_irq;
input[31:0] isr_val;
begin:decode_irq_body
integer i;
for(i=0; i<32; i=i+1) if(isr_val[i]) decode_irq = i;
end // UNMATCHED !!
endfunction
wire wb_irq;
reg irq_rising_edge = 0;
reg irq_falling_edge = 1;
reg irq_level_hi = 0;
reg irq_level_lo = 1;
integer irqn;
wb_test_interrupts
dut(
.rst_n_i (rst),
.wb_clk_i (clk),
.wb_addr_i (wb_addr[1:0]),
.wb_data_i (wb_data_o),
.wb_data_o (wb_data_i),
.wb_cyc_i (wb_cyc),
.wb_sel_i (wb_bwsel),
.wb_stb_i (wb_stb),
.wb_we_i (wb_we),
.wb_ack_o (wb_ack),
.wb_irq_o (wb_irq),
.irq_ipe_i (irq_rising_edge),
.irq_ine_i (irq_falling_edge),
.irq_il0_i (irq_level_lo ),
.irq_il1_i (irq_level_hi )
);
integer i;
integer fail = 0;
initial begin
#2000; @(posedge clk); #1; // wait until the DUT is reset
$display("Configure the interrupt controller - enable all interrupts");
wb_verbose(1);
wb_write(`ADDR_TESTIRQ_EIC_IER, 'hf);
end
initial begin
#10000; irq_rising_edge <= 1;
end
always@(wb_irq) begin
if(wb_irq == 1) begin
@(posedge clk); #1; // wait until the DUT is reset
wb_read(`ADDR_TESTIRQ_EIC_ISR, rval);
irqn = decode_irq(rval);
$display("Got interrupt: %d", irqn);
// acknowledge the interrupts
wb_write(`ADDR_TESTIRQ_EIC_ISR, (1<<irqn));
$display("Acknowledged IRQ: %d", irqn);
end
end
endmodule
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Logic /main/dut/rst_n_i
add wave -noupdate -format Logic /main/dut/wb_clk_i
add wave -noupdate -format Literal /main/dut/wb_addr_i
add wave -noupdate -format Literal /main/dut/wb_data_i
add wave -noupdate -format Literal /main/dut/wb_data_o
add wave -noupdate -format Logic /main/dut/wb_cyc_i
add wave -noupdate -format Literal /main/dut/wb_sel_i
add wave -noupdate -format Logic /main/dut/wb_stb_i
add wave -noupdate -format Logic /main/dut/wb_we_i
add wave -noupdate -format Logic /main/dut/wb_ack_o
add wave -noupdate -format Logic /main/dut/wb_irq_o
add wave -noupdate -format Logic /main/dut/irq_ipe_i
add wave -noupdate -format Logic /main/dut/irq_ine_i
add wave -noupdate -format Logic /main/dut/irq_il0_i
add wave -noupdate -format Logic /main/dut/irq_il1_i
add wave -noupdate -format Literal /main/dut/eic_idr_int
add wave -noupdate -format Logic /main/dut/eic_idr_write_int
add wave -noupdate -format Literal /main/dut/eic_ier_int
add wave -noupdate -format Logic /main/dut/eic_ier_write_int
add wave -noupdate -format Literal /main/dut/eic_imr_int
add wave -noupdate -format Literal /main/dut/eic_isr_clear_int
add wave -noupdate -format Literal /main/dut/eic_isr_status_int
add wave -noupdate -format Logic /main/dut/eic_isr_write_int
add wave -noupdate -format Literal /main/dut/irq_inputs_vector_int
add wave -noupdate -format Literal /main/dut/ack_sreg
add wave -noupdate -format Literal /main/dut/rddata_reg
add wave -noupdate -format Literal /main/dut/wrdata_reg
add wave -noupdate -format Literal /main/dut/bwsel_reg
add wave -noupdate -format Literal /main/dut/rwaddr_reg
add wave -noupdate -format Logic /main/dut/ack_in_progress
add wave -noupdate -format Logic /main/dut/wr_int
add wave -noupdate -format Logic /main/dut/rd_int
add wave -noupdate -format Logic /main/dut/bus_clock_int
add wave -noupdate -format Literal /main/dut/allones
add wave -noupdate -format Literal /main/dut/allzeros
add wave -noupdate -format Logic /main/dut/eic_irq_controller_inst/rst_n_i
add wave -noupdate -format Logic /main/dut/eic_irq_controller_inst/clk_i
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/irq_i
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/reg_imr_o
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/reg_ier_i
add wave -noupdate -format Logic /main/dut/eic_irq_controller_inst/reg_ier_wr_stb_i
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/reg_idr_i
add wave -noupdate -format Logic /main/dut/eic_irq_controller_inst/reg_idr_wr_stb_i
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/reg_isr_o
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/reg_isr_i
add wave -noupdate -format Logic /main/dut/eic_irq_controller_inst/reg_isr_wr_stb_i
add wave -noupdate -format Logic /main/dut/eic_irq_controller_inst/wb_irq_o
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/irq_mode
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/irq_mask
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/irq_pending
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/irq_i_d0
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/irq_i_d1
add wave -noupdate -format Literal /main/dut/eic_irq_controller_inst/irq_i_d2
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {10200000 ps} 0}
configure wave -namecolwidth 271
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
update
WaveRestoreZoom {7440472 ps} {12959528 ps}
reg [31:0] wb_addr = 0, wb_data_o = 0;
reg [3:0] wb_bwsel =4'b1111;
wire [31:0] wb_data_i;
wire wb_ack;
reg wb_cyc=0, wb_stb=0, wb_we= 0;
reg wb_tb_verbose = 1;
time last_access_t = 0;
task wb_verbose;
input onoff;
begin
wb_tb_verbose = onoff;
end
endtask // wb_verbose
task wb_write_generic;
input[31:0] addr;
input [31:0] data;
input [3:0] size;
begin
if(wb_tb_verbose) $display("WB write: addr %x, data %x", addr, data);
if($time != last_access_t) begin
@(posedge clk) #1;
end
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 1;
wb_bwsel = bytesel;
while(wb_ack == 0) begin @(posedge clk); #1; end
// @(posedge clk); #1
wb_cyc = 0;
wb_we=0;
wb_stb=0;
last_access_t = $time;
end
endtask // wb_write
task wb_write_byte;
input[31:0] addr;
input [31:0] data;
begin
if(wb_tb_verbose) $display("WB write_byte: addr %x, data %x", addr, data);
wb_stb=1;
wb_cyc=1;
wb_addr ={ 2'b00, addr[31:2] };
wb_data_o= (addr [1:0] == 2'b00) ? {data[7:0], 24'bx} :
(addr [1:0] == 2'b01) ? {8'bx, data[7:0], 16'bx} :
(addr [1:0] == 2'b10) ? {16'bx, data[7:0], 8'bx} :
(addr [1:0] == 2'b11) ? {24'bx, data[7:0]} : 32'bx;
wb_we = 1;
wb_bwsel = (addr [1:0] == 2'b00) ? 'b1000 :
(addr [1:0] == 2'b01) ? 'b0100 :
(addr [1:0] == 2'b10) ? 'b0010 :
(addr [1:0] == 2'b11) ? 'b0001 : 4'bxxxx;
while(wb_ack == 0) begin @(posedge clk); #1; end
@(posedge clk); #1;
wb_cyc = 0;
wb_we=0;
wb_stb=0;
end
endtask // wb_write
task wb_read;
input[31:0] addr;
output [31:0] data;
begin
wb_bwsel=4'hf;
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 0;
while(wb_ack == 0) @(posedge clk);
#1 data = wb_data_i;
// @(posedge clk);
wb_cyc = 0;
wb_we=0;
wb_stb=0;
if(wb_tb_verbose) $display("WB read: addr %x data %x", addr, data);
end
endtask // wb_read
task wb_read_byte;
input[31:0] addr;
output [31:0] data;
begin : task_wb_read_byte
reg [31:0] data_tmp;
wb_bwsel=4'hf;
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 0;
while(wb_ack == 0) @(posedge clk);
#1 data = (addr [1:0] == 2'b00) ? wb_data_i[31:24] :
(addr [1:0] == 2'b01) ? wb_data_i[23:16] :
(addr [1:0] == 2'b10) ? wb_data_i[15:8] :
(addr [1:0] == 2'b11) ? wb_data_i[7:0] : 4'bxxxx;
@(posedge clk);
wb_cyc = 0;
wb_we=0;
wb_stb=0;
if(wb_tb_verbose) $display("WB read byte: addr %x data %x", addr, data);
end
endtask // wb_read
\ No newline at end of file
// wishbone testbench utilities
begin : wb
reg [31:0] wb_addr = 0, wb_data_o = 0;
reg [3:0] wb_bwsel =4'b1111;
wire [31:0] wb_data_i;
wire wb_ack;
reg wb_cyc=0, wb_stb=0, wb_we= 0;
reg wb_tb_verbose = 1;
time last_access_t = 0;
task verbose;
input onoff;
begin
wb_tb_verbose = onoff;
end
endtask // wb_verbose
task rw_generic;
input[31:0] addr;
input [31:0] data_i;
output [31:0] data_o;
input rw;
input [3:0] size;
begin
if(wb_tb_verbose) $display("WB write: addr %x, data %x", addr, data);
if($time != last_access_t) begin
@(posedge clk) #0;
end
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_we = rw;
wb_bwsel = bytesel;
case(size)
4: wb_data_o=data_i;
2: begin
if(addr[1]) begin
wb_data_o[31:16] = data_i[15:0];
wb_bwsel = 4'b1100;
else
wb_data_o[15:0] = data_i[15:0];
wb_bwsel = 4'b0011;
end
end
1: begin
case(addr[1:0])
0: wb_data_o[7:0] = data_i[7:0]; wb_bwsel = 4'b0001;
1: wb_data_o[7:0] = data_i[7:0]; wb_bwsel = 4'b0001;
2: wb_data_o[7:0] = data_i[7:0]; wb_bwsel = 4'b0001;
3: wb_data_o[7:0] = data_i[7:0]; wb_bwsel = 4'b0001;
endcase // case(addr[1:0])
end
default: $error("Invalid operation size: ", size);
endcase // case(size)
#(`wbclk_period-1);
if(wb_ack == 0) begin
while(wb_ack == 0) begin @(posedge clk); #0; end
end
data_o = wb_data_i;
wb_cyc = 0;
wb_we=0;
wb_stb=0;
last_access_t = $time;
end
endtask // rw_generic
task wb_write_byte;
input[31:0] addr;
input [31:0] data;
begin
if(wb_tb_verbose) $display("WB write_byte: addr %x, data %x", addr, data);
wb_stb=1;
wb_cyc=1;
wb_addr ={ 2'b00, addr[31:2] };
wb_data_o= (addr [1:0] == 2'b00) ? {data[7:0], 24'bx} :
(addr [1:0] == 2'b01) ? {8'bx, data[7:0], 16'bx} :
(addr [1:0] == 2'b10) ? {16'bx, data[7:0], 8'bx} :
(addr [1:0] == 2'b11) ? {24'bx, data[7:0]} : 32'bx;
wb_we = 1;
wb_bwsel = (addr [1:0] == 2'b00) ? 'b1000 :
(addr [1:0] == 2'b01) ? 'b0100 :
(addr [1:0] == 2'b10) ? 'b0010 :
(addr [1:0] == 2'b11) ? 'b0001 : 4'bxxxx;
while(wb_ack == 0) begin @(posedge clk); #1; end
@(posedge clk); #1;
wb_cyc = 0;
wb_we=0;
wb_stb=0;
end
endtask // wb_write
task wb_read;
input[31:0] addr;
output [31:0] data;
begin
wb_bwsel=4'hf;
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 0;
while(wb_ack == 0) @(posedge clk);
#1 data = wb_data_i;
// @(posedge clk);
wb_cyc = 0;
wb_we=0;
wb_stb=0;
if(wb_tb_verbose) $display("WB read: addr %x data %x", addr, data);
end
endtask // wb_read
task wb_read_byte;
input[31:0] addr;
output [31:0] data;
begin : task_wb_read_byte
reg [31:0] data_tmp;
wb_bwsel=4'hf;
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 0;
while(wb_ack == 0) @(posedge clk);
#1 data = (addr [1:0] == 2'b00) ? wb_data_i[31:24] :
(addr [1:0] == 2'b01) ? wb_data_i[23:16] :
(addr [1:0] == 2'b10) ? wb_data_i[15:8] :
(addr [1:0] == 2'b11) ? wb_data_i[7:0] : 4'bxxxx;
@(posedge clk);
wb_cyc = 0;
wb_we=0;
wb_stb=0;
if(wb_tb_verbose) $display("WB read byte: addr %x data %x", addr, data);
end
endtask // wb_read
end
\ No newline at end of file
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library wbgen2;
use wbgen2.all;
entity wbgen2_eic is
generic (
g_num_interrupts : natural := 1;
g_irq00_mode : integer := 0;
g_irq01_mode : integer := 0;
g_irq02_mode : integer := 0;
g_irq03_mode : integer := 0;
g_irq04_mode : integer := 0;
g_irq05_mode : integer := 0;
g_irq06_mode : integer := 0;
g_irq07_mode : integer := 0;
g_irq08_mode : integer := 0;
g_irq09_mode : integer := 0;
g_irq0a_mode : integer := 0;
g_irq0b_mode : integer := 0;
g_irq0c_mode : integer := 0;
g_irq0d_mode : integer := 0;
g_irq0e_mode : integer := 0;
g_irq0f_mode : integer := 0;
g_irq10_mode : integer := 0;
g_irq11_mode : integer := 0;
g_irq12_mode : integer := 0;
g_irq13_mode : integer := 0;
g_irq14_mode : integer := 0;
g_irq15_mode : integer := 0;
g_irq16_mode : integer := 0;
g_irq17_mode : integer := 0;
g_irq18_mode : integer := 0;
g_irq19_mode : integer := 0;
g_irq1a_mode : integer := 0;
g_irq1b_mode : integer := 0;
g_irq1c_mode : integer := 0;
g_irq1d_mode : integer := 0;
g_irq1e_mode : integer := 0;
g_irq1f_mode : integer := 0
);
port(
rst_n_i : in std_logic; -- reset & system clock, as always :)
clk_i : in std_logic;
irq_i : in std_logic_vector(g_num_interrupts-1 downto 0); -- raw interrupt
-- inputs
-- interrupt mask regsiter (slv/bus read-only)
reg_imr_o : out std_logic_vector(g_num_interrupts-1 downto 0);
-- interrupt enable/disable registers (slv/bus pass-through)
reg_ier_i : in std_logic_vector(g_num_interrupts-1 downto 0);
reg_ier_wr_stb_i : in std_logic;
reg_idr_i : in std_logic_vector(g_num_interrupts-1 downto 0);
reg_idr_wr_stb_i : in std_logic;
-- interrupt status register (slv/bus write with LOAD_EXT)
reg_isr_o : out std_logic_vector(g_num_interrupts-1 downto 0);
reg_isr_i : in std_logic_vector(g_num_interrupts-1 downto 0);
reg_isr_wr_stb_i : in std_logic;
-- multiplexed wishbone irq output
wb_irq_o : out std_logic
);
end wbgen2_eic;
architecture syn of wbgen2_eic is
subtype t_irq_mode is integer;
type t_irq_mode_vec is array (0 to 31) of t_irq_mode;
constant c_IRQ_MODE_RISING_EDGE : t_irq_mode := 0;
constant c_IRQ_MODE_FALLING_EDGE : t_irq_mode := 1;
constant c_IRQ_MODE_LEVEL_0 : t_irq_mode := 2;
constant c_IRQ_MODE_LEVEL_1 : t_irq_mode := 3;
signal irq_mode : t_irq_mode_vec;
signal irq_mask : std_logic_vector(g_num_interrupts-1 downto 0);
signal irq_pending : std_logic_vector(g_num_interrupts-1 downto 0);
signal irq_i_d0 : std_logic_vector(g_num_interrupts-1 downto 0);
signal irq_i_d1 : std_logic_vector(g_num_interrupts-1 downto 0);
signal irq_i_d2 : std_logic_vector(g_num_interrupts-1 downto 0);
begin -- syn
irq_mode(0) <= g_irq00_mode;
irq_mode(1) <= g_irq01_mode;
irq_mode(2) <= g_irq02_mode;
irq_mode(3) <= g_irq03_mode;
irq_mode(4) <= g_irq04_mode;
irq_mode(5) <= g_irq05_mode;
irq_mode(6) <= g_irq06_mode;
irq_mode(7) <= g_irq07_mode;
irq_mode(8) <= g_irq08_mode;
irq_mode(9) <= g_irq09_mode;
irq_mode(10) <= g_irq0a_mode;
irq_mode(11) <= g_irq0b_mode;
irq_mode(12) <= g_irq0c_mode;
irq_mode(13) <= g_irq0d_mode;
irq_mode(14) <= g_irq0e_mode;
irq_mode(15) <= g_irq0f_mode;
irq_mode(16) <= g_irq10_mode;
irq_mode(17) <= g_irq11_mode;
irq_mode(18) <= g_irq12_mode;
irq_mode(19) <= g_irq13_mode;
irq_mode(20) <= g_irq14_mode;
irq_mode(21) <= g_irq15_mode;
irq_mode(22) <= g_irq16_mode;
irq_mode(23) <= g_irq17_mode;
irq_mode(24) <= g_irq18_mode;
irq_mode(25) <= g_irq19_mode;
irq_mode(26) <= g_irq1a_mode;
irq_mode(27) <= g_irq1b_mode;
irq_mode(28) <= g_irq1c_mode;
irq_mode(29) <= g_irq1d_mode;
irq_mode(30) <= g_irq1e_mode;
irq_mode(31) <= g_irq1f_mode;
process(clk_i, rst_n_i)
begin
if(rst_n_i = '0') then
irq_i_d0 <= (others => '0');
irq_i_d1 <= (others => '0');
irq_i_d1 <= (others => '0');
irq_pending <= (others => '0');
irq_mask <= (others => '0');
elsif rising_edge(clk_i) then
for i in 0 to g_num_interrupts-1 loop
irq_i_d0(i) <= irq_i(i);
irq_i_d1(i) <= irq_i_d0(i);
irq_i_d2(i) <= irq_i_d1(i);
if((reg_isr_i(i) = '1' and reg_isr_wr_stb_i = '1') or irq_mask(i) = '0') then
irq_pending(i) <= '0';
else
case irq_mode(i) is
when c_IRQ_MODE_LEVEL_0 => irq_pending(i) <= not irq_i_d2(i);
when c_IRQ_MODE_LEVEL_1 => irq_pending(i) <= irq_i_d2(i);
when c_IRQ_MODE_RISING_EDGE => irq_pending(i) <= irq_pending(i) or ((not irq_i_d2(i)) and irq_i_d1(i));
when c_IRQ_MODE_FALLING_EDGE => irq_pending(i) <= irq_pending(i) or ((not irq_i_d1(i)) and irq_i_d2(i));
when others => null;
end case;
end if;
end loop; -- i
if(reg_ier_wr_stb_i = '1') then
for i in 0 to g_num_interrupts-1 loop
if(reg_ier_i(i) = '1') then
irq_mask(i) <= '1';
end if;
end loop;
end if;
if(reg_idr_wr_stb_i = '1') then
for i in 0 to g_num_interrupts-1 loop
if(reg_idr_i(i) = '1') then
irq_mask(i) <= '0';
end if;
end loop;
end if;
end if;
end process;
-- generation of wb_irq_o
process(clk_i, rst_n_i)
begin
if(rst_n_i = '0') then
wb_irq_o <= '0';
elsif rising_edge(clk_i) then
if(irq_pending = std_logic_vector(to_unsigned(0, g_num_interrupts))) then
wb_irq_o <= '0';
else
wb_irq_o <= '1';
end if;
end if;
end process;
reg_imr_o <= irq_mask;
reg_isr_o <= irq_pending;
end syn;
......@@ -29,42 +29,41 @@ package wbgen2_pkg is
wr_a_i : in std_logic;
wr_b_i : in std_logic);
end component;
component wbgen2_eic
generic (
g_num_interrupts : natural;
g_irq00_mode : std_logic_vector(1 downto 0);
g_irq01_mode : std_logic_vector(1 downto 0);
g_irq02_mode : std_logic_vector(1 downto 0);
g_irq03_mode : std_logic_vector(1 downto 0);
g_irq04_mode : std_logic_vector(1 downto 0);
g_irq05_mode : std_logic_vector(1 downto 0);
g_irq06_mode : std_logic_vector(1 downto 0);
g_irq07_mode : std_logic_vector(1 downto 0);
g_irq08_mode : std_logic_vector(1 downto 0);
g_irq09_mode : std_logic_vector(1 downto 0);
g_irq0a_mode : std_logic_vector(1 downto 0);
g_irq0b_mode : std_logic_vector(1 downto 0);
g_irq0c_mode : std_logic_vector(1 downto 0);
g_irq0d_mode : std_logic_vector(1 downto 0);
g_irq0e_mode : std_logic_vector(1 downto 0);
g_irq0f_mode : std_logic_vector(1 downto 0);
g_irq10_mode : std_logic_vector(1 downto 0);
g_irq11_mode : std_logic_vector(1 downto 0);
g_irq12_mode : std_logic_vector(1 downto 0);
g_irq13_mode : std_logic_vector(1 downto 0);
g_irq14_mode : std_logic_vector(1 downto 0);
g_irq15_mode : std_logic_vector(1 downto 0);
g_irq16_mode : std_logic_vector(1 downto 0);
g_irq17_mode : std_logic_vector(1 downto 0);
g_irq18_mode : std_logic_vector(1 downto 0);
g_irq19_mode : std_logic_vector(1 downto 0);
g_irq1a_mode : std_logic_vector(1 downto 0);
g_irq1b_mode : std_logic_vector(1 downto 0);
g_irq1c_mode : std_logic_vector(1 downto 0);
g_irq1d_mode : std_logic_vector(1 downto 0);
g_irq1e_mode : std_logic_vector(1 downto 0);
g_irq1f_mode : std_logic_vector(1 downto 0));
g_irq00_mode : integer;
g_irq01_mode : integer;
g_irq02_mode : integer;
g_irq03_mode : integer;
g_irq04_mode : integer;
g_irq05_mode : integer;
g_irq06_mode : integer;
g_irq07_mode : integer;
g_irq08_mode : integer;
g_irq09_mode : integer;
g_irq0a_mode : integer;
g_irq0b_mode : integer;
g_irq0c_mode : integer;
g_irq0d_mode : integer;
g_irq0e_mode : integer;
g_irq0f_mode : integer;
g_irq10_mode : integer;
g_irq11_mode : integer;
g_irq12_mode : integer;
g_irq13_mode : integer;
g_irq14_mode : integer;
g_irq15_mode : integer;
g_irq16_mode : integer;
g_irq17_mode : integer;
g_irq18_mode : integer;
g_irq19_mode : integer;
g_irq1a_mode : integer;
g_irq1b_mode : integer;
g_irq1c_mode : integer;
g_irq1d_mode : integer;
g_irq1e_mode : integer;
g_irq1f_mode : integer);
port (
rst_n_i : in std_logic;
clk_i : in std_logic;
......
......@@ -20,8 +20,14 @@ function gen_wishbone_ports()
port(BIT, 0, "in", "wb_we_i"),
port(BIT, 0, "out", "wb_ack_o")
});
if(periph.irqcount > 0) then
table_join(ports, { port(BIT, 0, "out" ,"wb_irq_o"); });
end
add_global_ports(ports);
end
......@@ -52,11 +58,10 @@ function gen_bus_logic_wishbone()
gen_wishbone_ports();
gen_wishbone_signals();
foreach_reg(function(reg)
foreach_reg(ALL_REG_TYPES, function(reg)
gen_abstract_code(reg);
end );
local resetcode={};
local ackgencode={};
local preackcode={};
......@@ -65,61 +70,50 @@ function gen_bus_logic_wishbone()
table_join(resetcode, field.reset_code_main);
end );
foreach_reg(function(reg)
foreach_reg(ALL_REG_TYPES, function(reg)
table_join(resetcode, reg.reset_code_main);
end );
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
foreach_reg({TYPE_REG}, function(reg)
foreach_subfield(reg, function(field, reg)
table_join(ackgencode, field.ackgen_code);
end );
end
table_join(preackcode, field.ackgen_code_pre);
end);
table_join(ackgencode, reg.ackgen_code);
table_join(preackcode, reg.ackgen_code_pre);
end);
local fsmcode={};
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
foreach_subfield(reg, function(field, reg)
table_join(preackcode, field.ackgen_code_pre);
end );
end
end);
foreach_reg({TYPE_REG}, function(reg)
local acklen = find_max(reg, "acklen");
local rcode={};
local wcode={};
foreach_subfield(reg, function(field, reg) table_join(wcode, field.write_code); end );
foreach_subfield(reg, function(field, reg) table_join(rcode, field.read_code); end );
table_join(wcode, reg.write_code);
table_join(rcode, reg.read_code);
local rwcode = {
vif(vequal("wb_we_i" ,1), {
wcode
}, {
rcode
}); };
local fsmcode={};
table_join(rwcode, { va(vi("ack_sreg", math.max(acklen-1, 0)), 1); } );
table_join(rwcode, { va("ack_in_progress", 1); });
foreach_reg(function(reg)
if(reg.__type == TYPE_REG) then
local acklen = find_max(reg, "acklen");
local rcode={};
local wcode={};
foreach_subfield(reg, function(field, reg) table_join(wcode, field.write_code); end );
foreach_subfield(reg, function(field, reg) table_join(rcode, field.read_code); end );
local rwcode = {
vif(vequal("wb_we_i" ,1), {
wcode
}, {
rcode
}); };
table_join(rwcode, { va(vi("ack_sreg", math.max(acklen-1, 0)), 1); } );
table_join(rwcode, { va("ack_in_progress", 1); });
if(regbank_address_bits > 0) then
rwcode = { vcase(reg.base, rwcode); };
end
table_join(fsmcode, rwcode);
end
if(regbank_address_bits > 0) then
rwcode = { vcase(reg.base, rwcode); };
end
table_join(fsmcode, rwcode);
end );
if(regbank_address_bits > 0) then
table_join(fsmcode, { vcasedefault({
......@@ -142,21 +136,18 @@ function gen_bus_logic_wishbone()
foreach_reg(function(reg)
if(reg.__type == TYPE_RAM) then
local acklen = csel(options.register_data_output, 1, 0);
table_join(ramswitchcode, { vcase(reg.select_bits , {
vif(vequal("rd_int" ,1), {
va(vi("ack_sreg", 0), 1);
}, {
va(vi("ack_sreg", acklen), 1);
});
va("ack_in_progress", 1);
} ); } );
end
end
);
foreach_reg({TYPE_RAM}, function(reg)
local acklen = csel(options.register_data_output, 1, 0);
table_join(ramswitchcode, { vcase(reg.select_bits , {
vif(vequal("rd_int" ,1), {
va(vi("ack_sreg", 0), 1);
}, {
va(vi("ack_sreg", acklen), 1);
});
va("ack_in_progress", 1);
} ); } );
end);
table_join(ramswitchcode, {
vcasedefault({
......@@ -220,17 +211,14 @@ function gen_bus_logic_wishbone()
local output_mux_process = {vcomment("Data output multiplexer process"); vcombprocess(sens_list, mux_code);};
foreach_reg(function(reg)
if(reg.__type == TYPE_RAM) then
foreach_reg({TYPE_RAM}, function(reg)
table.insert(sens_list, reg.full_prefix.."_rddata_int");
table_join(mux_switch_code, {
vcase(reg.select_bits, {
va(vi("wb_data_o", reg.width-1, 0), reg.full_prefix.."_rddata_int");
} );
} );
end
end
);
end);
table.insert(sens_list, "wb_addr_i");
......@@ -243,8 +231,7 @@ function gen_bus_logic_wishbone()
local sens_list = { "wb_addr_i", "rd_int", "wr_int" };
local proc_body = { };
foreach_reg(function(reg)
if(reg.__type == TYPE_RAM) then
foreach_reg({TYPE_RAM}, function(reg)
-- table.insert(sens_list, reg.full_prefix.."_rddata_int");
table_join(proc_body, {vif(vequal(vi("wb_addr_i", address_bus_width-1, address_bus_width - address_bus_select_bits), reg.select_bits), {
va(reg.full_prefix.."_rd_int", "rd_int");
......@@ -253,31 +240,26 @@ function gen_bus_logic_wishbone()
va(reg.full_prefix.."_wr_int", 0);
va(reg.full_prefix.."_rd_int", 0);
}); });
end
end
);
end);
table_join(code, {vcomment("Read & write lines decoder for RAMs"); vcombprocess(sens_list, proc_body); });
else -- no RAMs in design? wire rddata_reg directly to wb_data_o
table_join(code, {vcomment("Drive the data output bus"); va("wb_data_o", "rddata_reg") } );
end
foreach_reg(function(reg)
foreach_reg(ALL_REG_TYPES, function(reg)
if(reg.extra_code ~= nil) then
table_join(code, {vcomment("extra code for reg/fifo/mem: "..reg.name);});
table_join(code, reg.extra_code);
end
foreach_subfield(reg, function(field, reg) table_join(code, {vcomment(field.name); field.extra_code}); end );
foreach_subfield(reg, function(field, reg)
if (field.extra_code ~= nil) then
table_join(code, {vcomment(field.name); field.extra_code});
end
end );
end);
if(address_bus_width > 0) then
......
#!/usr/bin/lua
if(arg[2] == nil) then
print( "usage: process_dofiles input.lua output_combined.lua");
os.exit(0);
end
local fin = io.open(arg[1],"r");
local fout = io.open(arg[2],"w");
function include_file(name)
local f= io.open(name,"r");
while true do
local line = fin.read(f);
if(line == nil) then break; end
if(string.match(line,"^#!") == nil) then
fout.write(fout, line.."\n");
end
end
io.close(f);
end
while true do
local line = fin.read(fin);
if(line == nil) then break; end
local fname = string.match(line,"^my_dofile%(\"(%S+)\"%)");
if(fname ~= nil) then
print("Including "..fname);
include_file(fname);
else
fout.write(fout, line.."\n");
end
end
io.close(fin);
This diff is collapsed.
This diff is collapsed.
......@@ -5,8 +5,7 @@
-- CERN BE-Co-HT
-- LICENSED UNDER GPL v2
-- EIC (tm) = Embedded Interrupt Controller
-- regs:
-- EIC (tm)(R) = Embedded Interrupt Controller. We need to register a trademark and start to sue people :)
--
-- EIC_IER = interrupt enable reg [passthru]
-- EIC_IDR = interrupt disable reg [passthru]
......@@ -14,18 +13,215 @@
-- EIC_ISR = interrupt status reg [rw, reset on write 1]
--
function wbgen_gen_irq_controller()
-- trigger = IRQ_POSEDGE, NEGEDGE, HIGH, LOW
-- name, desc
-- c/hdl_prefix
--function gen_eic_regfield_ier_idr(irq)
--local = { ["name"] = irq.name;
-- ["description"] = "Disable interrupt "..irq.name;
-- ["prefix"] = irq.prefix;
-- ["type"] = TYPE_BIT;
-- };
--end
function wbgen_generate_eic()
if(periph.irqcount == 0) then return; end
local irq_index = 0;
local irq_triggers = {};
local reg_idr = { ["__type"] = TYPE_REG;
["__blockindex"] = 1000000;
["align"] = 8;
["name"] = "Interrupt disable register";
["description"] = "Writing 1 disables handling of the interrupt associated with corresponding bit. Writin 0 has no effect.";
["c_prefix"] = "EIC_IDR";
["hdl_prefix"] = "EIC_IDR";
["signals"] = { signal (SLV, periph.irqcount, "eic_idr_int");
signal (BIT, 0, "eic_idr_write_int"); };
["write_code"] = { va("eic_idr_write_int", 1); };
["ackgen_code"] = { va("eic_idr_write_int", 0); };
["reset_code_main"] = { va("eic_idr_write_int", 0); };
["acklen"] = 1;
["extra_code"] = { va("eic_idr_int", vi("wrdata_reg", periph.irqcount-1, 0)); };
["no_std_regbank"] = true;
};
local reg_ier = { ["__type"] = TYPE_REG;
["__blockindex"] = 1000001;
["align"] = 1;
["name"] = "Interrupt enable register";
["description"] = "Writing 1 enables handling of the interrupt associated with corresponding bit. Writin 0 has no effect.";
["c_prefix"] = "EIC_IER";
["hdl_prefix"] = "EIC_IER";
["signals"] = { signal (SLV, periph.irqcount, "eic_ier_int");
signal (BIT, 0, "eic_ier_write_int"); };
["write_code"] = { va("eic_ier_write_int", 1); };
["ackgen_code"] = { va("eic_ier_write_int", 0); };
["reset_code_main"] = { va("eic_ier_write_int", 0); };
["acklen"] = 1;
["extra_code"] = { va("eic_ier_int", vi("wrdata_reg", periph.irqcount-1, 0)); };
["no_std_regbank"] = true;
};
local reg_isr = { ["__type"] = TYPE_REG;
["__blockindex"] = 1000002;
["align"] = 1;
["name"] = "Interrupt status register";
["description"] = "Each bit represents the state of corresponding interrupt. 1 means the interrupt is pending. Writing 1 to a bit clears the corresponding interrupt. Writing 0 has no effect.";
["c_prefix"] = "EIC_ISR";
["hdl_prefix"] = "EIC_ISR";
["signals"] = { signal (SLV, periph.irqcount, "eic_isr_clear_int");
signal (SLV, periph.irqcount, "eic_isr_status_int");
signal (BIT, 0, "eic_isr_write_int"); };
["write_code"] = { va("eic_isr_write_int", 1); };
["read_code"] = { va(vi("rddata_reg", periph.irqcount-1, 0), "eic_isr_status_int"); };
["ackgen_code"] = { va("eic_isr_write_int", 0); };
["reset_code_main"] = { va("eic_isr_write_int", 0); };
["acklen"] = 1;
["extra_code"] = { va("eic_isr_clear_int", vi("wrdata_reg", periph.irqcount-1, 0)); };
["no_std_regbank"] = true;
};
local reg_imr = { ["__type"] = TYPE_REG;
["__blockindex"] = 1000003;
["align"] = 1;
["name"] = "Interrupt mask register";
["description"] = "Shows which interrupts are enabled. 1 means that the interrupt associated with the bitfield is enabled";
["c_prefix"] = "EIC_IMR";
["hdl_prefix"] = "EIC_IMR";
["signals"] = { signal (SLV, periph.irqcount, "eic_imr_int"); };
["read_code"] = { va(vi("rddata_reg", periph.irqcount-1, 0), "eic_imr_int"); };
["acklen"] = 1;
["no_std_regbank"] = true;
};
foreach_reg({TYPE_IRQ}, function(irq)
irq.index = irq_index;
irq_index = irq_index + 1;
table.insert(irq_triggers, { ["index"] = irq.index; ["trigger"] = irq.trigger; });
fix_prefix(irq);
local field_isr = {
["__blockindex"] = irq.index;
["__type"] = TYPE_FIELD;
["type"] = BIT;
["name"] = irq.name;
["description"] = "read 1: interrupt "..irq.name.." is pending<br>read 0: interrupt not pending<br>write 1: clear interrupt "..irq.name.."<br>write 0: no effect";
["c_prefix"] = irq.c_prefix;
["hdl_prefix"] = irq.hdl_prefix;
["access"] = ACCESS_RW_RW;
};
local field_ier = {
["__blockindex"] = irq.index;
["__type"] = TYPE_FIELD;
["type"] = BIT;
["name"] = irq.name;
["description"] = "write 1: enable interrupt "..irq.name.." <br>0: no effect";
["c_prefix"] = irq.c_prefix;
["hdl_prefix"] = irq.hdl_prefix;
["access"] = ACCESS_WO_RO;
};
local field_idr = {
["__blockindex"] = irq.index;
["__type"] = TYPE_FIELD;
["type"] = BIT;
["name"] = irq.name;
["description"] = "write 1: disable interrupt "..irq.name.." <br>0: no effect";
["c_prefix"] = irq.c_prefix;
["hdl_prefix"] = irq.hdl_prefix;
["access"] = ACCESS_WO_RO;
};
local field_imr = {
["__blockindex"] = irq.index;
["__type"] = TYPE_FIELD;
["type"] = BIT;
["name"] = irq.name;
["description"] = "read 1: interrupt "..irq.name.." is enabled <br>read 0: interrupt "..irq.name.."is disabled";
["c_prefix"] = irq.c_prefix;
["hdl_prefix"] = irq.hdl_prefix;
["access"] = ACCESS_RO_WO;
};
local irq_list = {};
foreach_reg(function(irq) if(irq.__type == TYPE_IRQ) then
print("IRQ: "..irq.name);
end
end);
table.insert(reg_idr, field_idr);
table.insert(reg_isr, field_isr);
table.insert(reg_imr, field_imr);
table.insert(reg_ier, field_ier);
irq.full_prefix = string.lower("irq_"..irq.hdl_prefix);
irq.ports = { port(BIT, 0, "in", irq.full_prefix.."_i"); };
end);
add_global_signals( {
signal(SLV, periph.irqcount, "irq_inputs_vector_int");
});
-- add the EIC registers to peripheral
table.insert(periph, reg_idr);
table.insert(periph, reg_ier);
table.insert(periph, reg_imr);
table.insert(periph, reg_isr);
local maps = { vgm("g_num_interrupts", periph.irqcount);
vpm("clk_i", "bus_clock_int");
vpm("rst_n_i", "rst_n_i");
vpm("irq_i", "irq_inputs_vector_int");
vpm("reg_imr_o", "eic_imr_int");
vpm("reg_ier_i", "eic_ier_int");
vpm("reg_ier_wr_stb_i", "eic_ier_write_int");
vpm("reg_idr_i", "eic_idr_int");
vpm("reg_idr_wr_stb_i", "eic_idr_write_int");
vpm("reg_isr_o", "eic_isr_status_int");
vpm("reg_isr_i", "eic_isr_clear_int");
vpm("reg_isr_wr_stb_i", "eic_isr_write_int");
vpm("wb_irq_o", "wb_irq_o");
};
local last_i;
for i,v in ipairs(irq_triggers) do
table_join(maps, { vgm(string.format("g_irq%02x_mode", v.index), v.trigger) });
last_i = i;
end
-- f****ing stupid VHDL :/
for i=last_i, 31 do
table_join(maps, { vgm(string.format("g_irq%02x_mode", i), 0) });
end
local irq_unit_code = { vinstance("eic_irq_controller_inst", "wbgen2_eic", maps ); };
foreach_reg({TYPE_IRQ}, function(irq)
table_join(irq_unit_code, {va(vi("irq_inputs_vector_int", irq.index), irq.full_prefix.."_i")});
end);
local fake_irq = {
["__type"] = TYPE_IRQ;
["name"] = "IRQ_CONTROLLER";
["prefix"] = "IRQ_CONTROLLER";
["extra_code"] = irq_unit_code;
};
table.insert(periph, fake_irq);
end
......@@ -2,8 +2,6 @@
wbgen2_version="0.5"
device_family="altera_cyclone3";
options = {};
options.reset_type = "asynchronous";
options.target_interconnect = "wb-classic";
......@@ -88,28 +86,33 @@ parse_args(arg);
dofile(input_wb_file);
if(periph == nil) then die ("missing peripheral declaration"); end
foreach_reg(
function(reg)
reg.total_size=0;
reg.current_offset=0;
end
);
foreach_field( fix_prefix );
foreach_field( fix_access );
foreach_reg( fix_prefix );
foreach_reg(ALL_REG_TYPES, fix_prefix );
periph = fix_prefix(periph);
wbgen_count_subblocks();
wbgen_generate_eic();
foreach_reg(ALL_REG_TYPES, function(reg)
reg.total_size=0;
reg.current_offset=0;
end);
foreach_field(calc_size);
foreach_reg(check_max_size);
foreach_reg({TYPE_REG, TYPE_RAM, TYPE_FIFO}, check_max_size);
foreach_field(calc_field_offsets);
foreach_reg(calc_address_sizes);
foreach_reg({TYPE_REG, TYPE_RAM, TYPE_FIFO}, calc_address_sizes);
assign_addresses();
......
......@@ -638,7 +638,10 @@ end
-- generates VHDL for single register
function gen_abstract_code(reg)
if(reg.no_std_regbank == true) then
return;
end
if(reg.__type == TYPE_RAM) then
gen_code_ram(reg);
else
......
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