Discussion:
addr_gen_wb - the HDL and address map generator for WB/IPbus connected hierarchical FPGA systems
(too old to reply)
Wojciech M. Zabołotny
2018-11-17 23:25:26 UTC
Permalink
Attached are the sources of the addr_gen_wb - the simple system that
allows you to generate the HDL code needed to access registers in the
Wishbone or IPbus connected hierarchical FPGA system.
The concept of the system is based on the wbgen2
(https://www.ohwr.org/projects/wishbone-gen/wiki/wbgen2-documentation)
written by Tomasz Włostowski, and on multiple suggestions regarding
to wbgen2 improvement, provided by Marek Gumiński.
Myh source is published under LGPL v2 license (like the wbgen2, that was
my inspiration).

The sources contain also a simple demo running with GHDL and Python3, and
showing the operation of the system.

#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.15.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the '#!/bin/sh' line above, then type 'sh FILE'.
#
lock_dir=_sh17500
# Made on 2018-11-18 00:19 CET by <***@wzab>.
# Source directory was '/tmp/uuuu'.
#
# Existing files will *not* be overwritten, unless '-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 757 -rw-r--r-- addr_gen_wb/README.md
# 22159 -rw-r--r-- addr_gen_wb/src/wb_block.py
# 1524 -rwxr-xr-x addr_gen_wb/src/addr_gen_wb.py
# 332 -rwxr-xr-x addr_gen_wb/test/prepare.sh
# 0 -rw-r--r-- addr_gen_wb/test/gen/dummy
# 490 -rw-r--r-- addr_gen_wb/test/example1.xml
# 1375 -rw-r--r-- addr_gen_wb/test/Makefile
# 3201 -rwxr-xr-x addr_gen_wb/test/python/cbus.py
# 1048 -rwxr-xr-x addr_gen_wb/test/python/wb_test.py
# 227 -rwxr-xr-x addr_gen_wb/test/wb_test.sh
# 57 -rwxr-xr-x addr_gen_wb/test/generate.sh
# 2340 -rw-r--r-- addr_gen_wb/test/hdl/wb_test_top_tb.vhd
# 1087 -rw-r--r-- addr_gen_wb/test/hdl/main.vhd
# 9581 -rw-r--r-- addr_gen_wb/test/hdl/sim_wb_ctrl.vhd
# 1215 -rw-r--r-- addr_gen_wb/test/hdl/wb_test_top.vhd
# 992 -rw-r--r-- addr_gen_wb/test/hdl/sys1.vhd
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
echo 'Note: not verifying md5sums. Consider installing GNU coreutils.'
if test "X$1" = "X-c"
then keep_file=''
else keep_file=true
fi
echo=echo
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=
locale_dir=
set_echo=false

for dir in $PATH
do
if test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
case `$dir/gettext --version 2>&1 | sed 1q` in
*GNU*) gettext_dir=$dir
set_echo=true
break ;;
esac
fi
done

if ${set_echo}
then
set_echo=false
for dir in $PATH
do
if test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
set_echo=true
break
fi
done

if ${set_echo}
then
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
fi
IFS="$save_IFS"
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
then shar_n= shar_c='
'
else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901

if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
test ! -f ${st1} && test -f ${f}; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'

elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'

elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
test ! -f ${st3} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$2 "$8"'

else
shar_touch=:
echo
${echo} 'WARNING: not restoring timestamps. Consider getting and
installing GNU '\''touch'\'', distributed in GNU coreutils...'
echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir} ; then :
else ${echo} "lock directory ${lock_dir} exists"
exit 1
fi
if mkdir ${lock_dir}
then ${echo} "x - created lock directory ${lock_dir}."
else ${echo} "x - failed to create lock directory ${lock_dir}."
exit 1
fi
# ============= addr_gen_wb/README.md ==============
if test ! -d 'addr_gen_wb'; then
mkdir 'addr_gen_wb'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb."
else ${echo} "x - failed to create directory addr_gen_wb."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/README.md'
then
${echo} "x - SKIPPING addr_gen_wb/README.md (file already exists)"

else
${echo} "x - extracting addr_gen_wb/README.md (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/README.md' &&
# adr\_gen\_wb.py - register access for hierarchical Wishbone connected systems #
The [wbgen2](https://www.ohwr.org/projects/wishbone-gen/wiki/wbgen2-documentation) is a very nice tool. However, it has certain limitations that were critical for me. Namely it does not support arrays of registers, and does not support nested blocks. Probably it can be extended to support those features, but I definitely prefere to write code generators in Python than in Lua. Therefore I decided to try to write adr\_gen\_wb.py in Python, almost from scratch.
X
The code is licensed under GPL v2 license.
The generated code is free, and you can freely use it in your design.
X
I'd like to thank Marek Gumiński for important suggestions related to concept of that solution.
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/README.md'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/README.md'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/README.md failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/README.md': 'MD5 check failed'
) << \SHAR_EOF
17d7cdf5aff871ad8be87c18d29c8630 addr_gen_wb/README.md
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/README.md'` -ne 757 && \
${echo} "restoration warning: size of 'addr_gen_wb/README.md' is not 757"
fi
fi
# ============= addr_gen_wb/src/wb_block.py ==============
if test ! -d 'addr_gen_wb'; then
mkdir 'addr_gen_wb'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb."
else ${echo} "x - failed to create directory addr_gen_wb."
exit 1
fi
fi
if test ! -d 'addr_gen_wb/src'; then
mkdir 'addr_gen_wb/src'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/src."
else ${echo} "x - failed to create directory addr_gen_wb/src."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/src/wb_block.py'
then
${echo} "x - SKIPPING addr_gen_wb/src/wb_block.py (file already exists)"

else
${echo} "x - extracting addr_gen_wb/src/wb_block.py (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/src/wb_block.py' &&
"""
This is the script that generates the VHDL code needed to access
the registers in a hierarchical Wishbone-conencted system.
X
Written by Wojciech M. Zabolotny
(***@gmail.com or ***@ise.pw.edu.pl)
X
The code is published under LGPL V2 license
X
This file implements the class handling a Wishbone connected block
"""
import re
import zlib
X
# Template for generation of the VHDL package
templ_pkg = """\
library ieee;
X
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
X
library work;
use work.wishbone_pkg.all;
X
package {p_entity}_pkg is
{p_package}
end {p_entity}_pkg;
X
package body {p_entity}_pkg is
{p_package_body}
end {p_entity}_pkg;
"""
X
# Template for generation of the VHDL code
X
templ_wb = """\
--- This code is automatically generated by the addrgen_wb.py tool
--- Please don't edit it manaully, unless you really have to do it.
X
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.{p_entity}_pkg.all;
X
entity {p_entity} is
X port (
X slave_i : in t_wishbone_slave_in;
X slave_o : out t_wishbone_slave_out;
{subblk_busses}
{signal_ports}
X rst_n_i : in std_logic;
X clk_sys_i : in std_logic
X );
X
end {p_entity};
X
architecture gener of {p_entity} is
{signal_decls}
X -- Internal WB declaration
X signal int_regs_wb_m_o : t_wishbone_master_out;
X signal int_regs_wb_m_i : t_wishbone_master_in;
X signal int_addr : std_logic_vector({reg_addr_bits}-1 downto 0);
X signal wb_up_o : t_wishbone_slave_out_array(0 to 0);
X signal wb_up_i : t_wishbone_slave_in_array(0 to 0);
X signal wb_m_o : t_wishbone_master_out_array(0 to {nof_subblks}-1);
X signal wb_m_i : t_wishbone_master_in_array(0 to {nof_subblks}-1);
X
X -- Constants
X constant c_address : t_wishbone_address_array(0 to {nof_subblks}-1) := {p_addresses};
X constant c_mask : t_wishbone_address_array(0 to {nof_subblks}-1) := {p_masks};
X
begin
X wb_up_i(0) <= slave_i;
X slave_o <= wb_up_o(0);
X int_addr <= int_regs_wb_m_o.adr({reg_addr_bits}-1 downto 0);
X
-- Main crossbar
X xwb_crossbar_1: entity work.xwb_crossbar
X generic map (
X g_num_masters => 1,
X g_num_slaves => {nof_subblks},
X g_registered => {p_registered},
X g_address => c_address,
X g_mask => c_mask)
X port map (
X clk_sys_i => clk_sys_i,
X rst_n_i => rst_n_i,
X slave_i => wb_up_i,
X slave_o => wb_up_o,
X master_i => wb_m_i,
X master_o => wb_m_o,
X sdb_sel_o => open);
X
-- Process for register access
X process(clk_sys_i)
X begin
X if rising_edge(clk_sys_i) then
X if rst_n_i = '0' then
X -- Reset of the core
X int_regs_wb_m_i <= c_DUMMY_WB_MASTER_IN;
X else
X -- Normal operation
X int_regs_wb_m_i.rty <= '0';
X int_regs_wb_m_i.ack <= '0';
X int_regs_wb_m_i.err <= '0';
{signals_idle}
X if (int_regs_wb_m_o.cyc = '1') and (int_regs_wb_m_o.stb = '1') then
X int_regs_wb_m_i.err <= '1'; -- in case of missed address
X -- Access, now we handle consecutive registers
X case int_addr is
{register_access}
X when {block_id_addr} =>
X int_regs_wb_m_i.dat <= {block_id};
X int_regs_wb_m_i.ack <= '1';
X int_regs_wb_m_i.err <= '0';
X when {block_ver_addr} =>
X int_regs_wb_m_i.dat <= {block_ver};
X int_regs_wb_m_i.ack <= '1';
X int_regs_wb_m_i.err <= '0';
X when others =>
X int_regs_wb_m_i.dat <= x"A5A5A5A5";
X int_regs_wb_m_i.ack <= '1';
X int_regs_wb_m_i.err <= '0';
X end case;
X end if;
X end if;
X end if;
X end process;
{cont_assigns}
end architecture;
"""
blocks={}
X
class wb_field(object):
X def __init__(self,fl,lsb):
X self.name = fl.attrib['name']
X self.lsb = lsb
X self.size = int(fl.attrib['width'])
X self.msb = lsb + self.size - 1
X self.type = fl.get('type','std_logic_vector')
X
X
X
class wb_reg(object):
X """ The class wb_reg describes a single register
X """
X def __init__(self,el,adr):
X """
X The constructor gets the XML node defining the register
X """
X nregs=int(el.get('reps',1))
X self.regtype = el.tag
X self.type = el.get('type','std_logic_vector')
X self.base = adr
X self.size = nregs
X self.name = el.attrib['name']
X self.ack = int(el.get('ack',0))
X self.stb = int(el.get('stb',0))
X # Read list of fields
X self.fields=[]
X self.free_bit=0
X for fl in el.findall('field'):
X fdef=wb_field(fl,self.free_bit)
X self.free_bit += fdef.size
X if self.free_bit > 32:
X raise Exception("Total width of fields in register " +self.name+ " is above 32-bits")
X self.fields.append(fdef)
X
X
X def gen_vhdl(self,parent):
X """
X The method generates the VHDL block responsible for access
X to the registers.
X We append our definitions to the appropriate sections
X in the parrent block.
X
X We need to generate two sections:
X * Declaration of signals used to input or output the signal,
X and the optional ACK or STB flags
X * Read or write sequence to be embedded in the process
X """
X dt=""
X dtb=""
X dti=""
X # Generate the type corresponding to the register
X tname = "t_"+self.name
X if len(self.fields) == 0:
X # Simple register, no fields
X dt+="subtype "+tname+" is "+\
X self.type+"(31 downto 0);\n"
X else:
X # Register with fields, we have to create a record
X dt+="type "+tname+" is record\n"
X for fl in self.fields:
X dt+= " "+fl.name+":"+fl.type+"("+str(fl.size-1)+" downto 0);\n"
X dt+="end record;\n\n"
X
X #Conversion function stlv to record
X dt+="function stlv2"+tname+"(x : std_logic_vector) return "+tname+";\n"
X dtb+="function stlv2"+tname+"(x : std_logic_vector) return "+tname+" is\n"
X dtb+="variable res : "+tname+";\n"
X dtb+="begin\n"
X for fl in self.fields:
X dtb+=" res."+fl.name+" := "+fl.type+"(x("+str(fl.msb)+" downto "+str(fl.lsb)+"));\n"
X dtb+=" return res;\n"
X dtb+="end stlv2"+tname+";\n\n"
X
X #conversion function record to stlv
X dt+="function "+tname+"2stlv(x : "+tname+") return std_logic_vector;\n"
X dtb+="function "+tname+"2stlv(x : "+tname+") return std_logic_vector is\n"
X dtb+="variable res : std_logic_vector(31 downto 0);\n"
X dtb+="begin\n"
X dtb+=" res := (others => '0');\n"
X for fl in self.fields:
X dtb+=" res("+str(fl.msb)+" downto "+str(fl.lsb)+") := std_logic_vector(x."+fl.name+");\n"
X dtb+=" return res;\n"
X dtb+="end "+tname+"2stlv;\n\n"
X # If this is a vector of registers, create the array type
X if self.size > 1:
X dt+="type "+tname+"_array is array(0 to "+ str(self.size-1) +") of "+tname+";\n"
X # Append the generated types to the parents package section
X parent.add_templ('p_package',dt,0)
X parent.add_templ('p_package_body',dtb,0)
X
X # Now generate the entity ports
X sfx = '_i'
X sdir = "in "
X if self.regtype == 'creg':
X sfx = '_o'
X sdir = "out "
X if self.size == 1:
X dt=self.name+sfx+" : "+sdir+" "+tname+";\n"
X else:
X dt=self.name+sfx+" : "+sdir+" "+tname+"_array;\n"
X # Now we generate the STB or ACK ports (if required)
X if self.regtype == 'creg' and self.stb == 1:
X dt += self.name+sfx+"_stb : out std_logic;\n"
X # We need to generate STB output
X pass # To be implemented!
X if self.regtype == 'sreg' and self.ack == 1:
X dt += self.name+sfx+"_ack : out std_logic;\n"
X # We need to generate ACK output
X pass # To be implemented!
X parent.add_templ('signal_ports',dt,4)
X # Generate the intermediate signals for output ports
X # (because they can't be read back)
X if self.regtype == 'creg':
X #Create the intermediate readable signal
X if self.size == 1:
X dt = "signal int_"+self.name+sfx+" : "+tname+";\n"
X else:
X dt = "signal int_"+self.name+sfx+" : "+tname+"_array;\n"
X dt2 = self.name+sfx+" <= int_"+self.name+sfx+";\n"
X parent.add_templ('signal_decls',dt,4)
X parent.add_templ('cont_assigns',dt2,2)
X # Generate the signal assignment in the process
X for i in range(0,self.size):
X # We prepare the index string used in case if this is a vector of registers
X if self.size > 1:
X ind ="("+str(i)+")"
X else:
X ind = ""
X dt= "when \""+format(self.base+i,"0"+str(parent.reg_addr_bits)+"b")+"\" => -- "+hex(self.base+i)+"\n"
X # The conversion functions
X if len(self.fields)==0:
X conv_fun="std_logic_vector"
X iconv_fun=self.type
X else:
X conv_fun="t_"+self.name+"2stlv"
X iconv_fun="stlv2t_"+self.name
X # Read access
X if self.regtype == 'sreg':
X dt+=" int_regs_wb_m_i.dat <= "+conv_fun+"("+self.name+"_i"+ind+");\n"
X if self.ack == 1:
X dt += " if int_regs_wb_m_i.ack = \'0\' then\n" #We shorten the STB to a single clock
X dt += " "+self.name+sfx+"_ack <= '1';\n"
X dt += " end if;\n"
X # Add clearing of ACK signal at the begining of the process
X dti += self.name+sfx+"_ack <= '0';\n"
X else:
X dt+=" int_regs_wb_m_i.dat <= "+conv_fun+"(int_"+self.name+"_o"+ind+");\n"
X # Write access
X if self.regtype == 'creg':
X dt+=" if int_regs_wb_m_o.we = '1' then\n"
X dt+=" int_"+self.name+"_o"+ind+" <= "+iconv_fun+"(int_regs_wb_m_o.dat);\n"
X if self.stb == 1:
X dt += " if int_regs_wb_m_i.ack = \'0\' then\n" #We shorten the STB to a single clock
X dt += " "+self.name+sfx+"_stb <= '1';\n"
X dt += " end if;\n"
X # Add clearing of STB signal at the begining of the process
X dti += self.name+sfx+"_stb <= '0';\n"
X dt+=" end if;\n"
X dt += " int_regs_wb_m_i.ack <= '1';\n"
X dt += " int_regs_wb_m_i.err <= '0';\n"
X parent.add_templ('register_access',dt,10)
X parent.add_templ('signals_idle',dti,10)
X
X def gen_ipbus_xml(self,reg_base):
X # The generated code depends on the fact it is a single register or the vector of registers
X res=""
X for rn in range(0,self.size):
X adr = reg_base+self.base+rn
X # The name format depends whether its a single register or an item in a vector
X if self.size == 1:
X rname = self.name
X else:
X rname = self.name + "["+str(rn)+"]"
X # Set permissions
X if self.regtype == 'creg':
X perms = "rw"
X elif self.regtype == 'sreg':
X perms = "r"
X else:
X raise Exception("Unknown type of register")
X # Finally the format of the description depends on the presence of bitfields
X if len(self.fields) == 0:
X res+=" <node id=\""+rname+"\" address=\"0x"+format(adr,"08x")+"\" permission=\""+perms+"\"/>\n"
X else:
X res+=" <node id=\""+rname+"\" address=\"0x"+format(adr,"08x")+"\" permission=\""+perms+"\">\n"
X for bf in self.fields:
X maskval=((1<<(bf.msb+1))-1) ^ ((1<<bf.lsb)-1)
X mask = format(maskval,"08x")
X res+=" <node id=\""+bf.name+"\" mask=\"0x"+mask+"\"/>\n"
X res+=" </node>\n"
X
X return res
X
class wb_area(object):
X """ The class representing the address area
X """
X def __init__(self,size,name,obj,reps):
X self.name=name
X self.size=size
X self.obj=obj
X self.adr=0
X self.mask=0
X self.total_size=0
X self.reps=reps
X def sort_key(self):
X return self.size
X
class wb_block(object):
X def __init__(self,el):
X """
X The constructor takes an XML node that describes the block
X It also calculates the number of registers, and creates
X the description of the record
X """
X self.used = False # Mark the block as not used yet
X self.templ_dict={}
X self.name = el.attrib['name']
X # We prepare the list of address areas
X self.areas=[]
X # We prepare the table for storing the registers.
X self.regs=[]
X self.free_reg_addr=2 # The first free address after ID & VER
X # Prepare the list of subblocks
X self.subblks=[]
X for child in el.findall("*"):
X # Now for registers we allocate addresses in order
X # We don't to alignment (yet)
X if child.tag == 'creg':
X # This is a control register
X reg = wb_reg(child,self.free_reg_addr)
X self.free_reg_addr += reg.size
X self.regs.append(reg)
X elif child.tag == 'sreg':
X # This is a status register
X reg = wb_reg(child,self.free_reg_addr)
X self.free_reg_addr += reg.size
X self.regs.append(reg)
X elif child.tag == 'subblock':
X # This is a subblock definition
X # We only add it to the list, the addresses can't be allocated yet
X self.subblks.append(child)
X else:
X # Unknown child
X raise Exception("Unknown node in block: "+el.name)
X # After that procedure, the field free_reg_addr contains
X # the length of the block of internal registers
X self.reg_addr_bits = (self.free_reg_addr-1).bit_length()
X
X def analyze(self):
X # Add the length of the local addresses to the list of areas
X self.areas.append(wb_area(self.free_reg_addr,"int_regs",None,1))
X # Scan the subblocks
X for sblk in self.subblks:
X #@!@ Here we must to correct something! The name of the subblock
X #Is currently lost. We must to decide how it should be passed
X #To the generated code@!@
X bl = blocks[sblk.attrib['type']]
X # If the subblock was not analyzed yet, analyze it now
X if len(bl.areas)==0:
X bl.analyze()
X # Now we can be sure, that it is analyzed, so we can
X # add its address space to ours.
X # Check if this is a vector of subblocks
X reps = int(sblk.get('reps',1))
X print("reps:"+str(reps))
X # Now recalculate the size of the area, considering possible
X # block repetitions
X addr_size = bl.addr_size * reps
X self.areas.append(wb_area(addr_size,sblk.get('name'),bl,reps))
X # Now we can calculate the total length of address space
X # We use the simplest algorithm - all blocks are sorted,
X # their size is rounded up to the nearest power of 2
X # They are allocated in order.
X cur_base = 0
X self.areas.sort(key=wb_area.sort_key, reverse=True)
X for ar in self.areas:
X if ar.obj==None:
X # This is the register block
X self.reg_base = cur_base
X ar.adr = cur_base
X ar.adr_bits = (ar.size-1).bit_length()
X ar.total_size = 1 << ar.adr_bits
X # Now we shift the position of the next block
X cur_base += ar.total_size
X print("added size:"+str(ar.total_size))
X self.addr_size = cur_base
X # We must adjust the address space to the power of two
X self.adr_bits = (self.addr_size-1).bit_length()
X self.addr_size = 1 << self.adr_bits
X self.used = True
X # In fact, here we should be able to generate the HDL code
X
X print('analyze: '+self.name+" addr_size:"+str(self.addr_size))
X
X def add_templ(self,templ_key,value,indent):
X """ That function adds the new text to the dictionary
X used to fill the templates for code generation.
X """
X if templ_key not in self.templ_dict:
X self.templ_dict[templ_key] = ""
X # Now we add all lines from value, providing the appropriate indentation
X for ln in re.findall(r'.*\n?',value)[:-1]:
X if ln != "":
X self.templ_dict[templ_key] += indent*" " + ln
X
X def gen_vhdl(self,ver_id):
X # To fill the template, we must to set the following values:
X # p_entity, valid_bits
X
X # subblk_busses, signal_ports, signal_decls
X # nof_subblks,
X # subblk_assignments,
X # n_slaves,
X # p_registered,
X # p_addresses, p_masks
X # block_id, block_ver - to verify that design matches the software
X
X # First - generate code for registers
X # We give empty declaration in case if the block does not contain
X # any registers
X self.add_templ('p_package','',0)
X self.add_templ('p_package_body','',0)
X self.add_templ('signal_decls','',0)
X self.add_templ('register_access','',0)
X self.add_templ('subblk_busses','',0)
X for reg in self.regs:
X #generate
X reg.gen_vhdl(self)
X # Generate code for connection of all areas
X ar_adr_bits=[]
X ar_addresses=[]
X n_ports=0
X dt = ""
X for ar in self.areas:
X if (ar.reps == 1):
X ar.first_port = n_ports
X ar.last_port = n_ports
X n_ports += 1
X ar_addresses.append(ar.adr)
X ar_adr_bits.append(ar.adr_bits)
X #generate the entity port but not for internal registers
X if ar.obj != None:
X dt = ar.name+"_wb_m_o : out t_wishbone_master_out;\n"
X dt += ar.name+"_wb_m_i : in t_wishbone_master_in;\n"
X self.add_templ('subblk_busses',dt,4)
X #generate the signal assignment
X dt = "wb_m_i("+str(ar.first_port)+") <= "+ar.name+"_wb_m_i;\n"
X dt += ar.name+"_wb_m_o <= "+"wb_m_o("+str(ar.first_port)+");\n"
X self.add_templ('cont_assigns',dt,4)
X else:
X # The area is associated with the vector of subblocks
X ar.first_port = n_ports
X ar.last_port = n_ports+ar.reps-1
X n_ports += ar.reps
X #generate the entity port
X dt = ar.name+"_wb_m_o : out t_wishbone_master_out_array("+str(ar.first_port)+" to "+str(ar.last_port)+");\n"
X dt += ar.name+"_wb_m_i : in t_wishbone_master_in_array("+str(ar.first_port)+" to "+str(ar.last_port)+");\n"
X self.add_templ('subblk_busses',dt,4)
X # Now we have to assign addresses and masks for each subblock and connect the port
X base = ar.adr
X nport = ar.first_port
X for i in range(0,ar.reps):
X ar_addresses.append(base)
X base += ar.obj.addr_size
X ar_adr_bits.append(ar.obj.adr_bits)
X dt = "wb_m_i("+str(nport)+") <= "+ar.name+"_wb_m_i("+str(i)+");\n"
X dt += ar.name+"_wb_m_o("+str(i)+") <= "+"wb_m_o("+str(nport)+");\n"
X self.add_templ('cont_assigns',dt,4)
X nport += 1
X #Now generate vectors with addresses and masks
X adrs="("
X masks="("
X for i in range(0,n_ports):
X if i>0:
X adrs+=","
X masks+=","
X adrs +=str(i)+"=>\""+format(ar_addresses[i],"032b")+"\""
X #Calculate the mask
X maskval = ((1<<self.adr_bits)-1) ^ ((1<<ar_adr_bits[i])-1)
X masks +=str(i)+"=>\""+format(maskval,"032b")+"\""
X adrs += ")"
X masks += ")"
X #Generate the register address for
X self.add_templ('block_id_addr',"\""+format(0,"0"+str(self.reg_addr_bits)+"b")+"\"",0)
X self.add_templ('block_ver_addr',"\""+format(1,"0"+str(self.reg_addr_bits)+"b")+"\"",0)
X self.add_templ('reg_addr_bits',str(self.reg_addr_bits),0)
X block_id_val = zlib.crc32(bytes(self.name.encode('utf-8')))
X self.add_templ('block_id',"x\""+format(block_id_val,"08x")+"\"",0)
X self.add_templ('block_ver',"x\""+format(ver_id,"08x")+"\"",0)
X self.add_templ('p_addresses',adrs,0)
X self.add_templ('p_masks',masks,0)
X self.add_templ('p_registered','false',0)
X self.add_templ('nof_subblks',str(n_ports),0)
X self.add_templ('p_entity',self.name+"_wb",0)
X # All template is filled, so we can now generate the files
X print(self.templ_dict)
X with open(self.name+"_wb.vhd","w") as fo:
X fo.write(templ_wb.format(**self.templ_dict))
X with open(self.name+"_pkg.vhd","w") as fo:
X fo.write(templ_pkg.format(**self.templ_dict))
X
X def gen_ipbus_xml(self,ver_id):
X """ This function generates the address map in the XML format
X
X """
X res="<node id=\""+self.name+"\">\n"
X # Iterate the areas, generating the addresses
X for ar in self.areas:
X if ar.obj == None:
X #Registers area
X #Add two standard registers - ID and VER
X adr = ar.adr
X res+=" <node id=\"ID\" address=\""+format(adr,"08x")+"\" permission=\"r\"/>\n"
X res+=" <node id=\"VER\" address=\""+format(adr+1,"08x")+"\" permission=\"r\"/>\n"
X #Now add other registers in a loop
X for reg in self.regs:
X res += reg.gen_ipbus_xml(adr)
X else:
X #Subblock or vector of subblocks
X if ar.reps==1:
X #Single subblock
X res += " <node id=\""+ar.name+"\""+\
X " address=\"0x"+format(ar.adr,"08x")+"\""+\
X " module=\""+ar.obj.name+"_address.xml\"/>\n"
X else:
X #Vector of subblocks
X for nb in range(0,ar.reps):
X res += " <node id=\""+ar.name+"["+str(nb)+"]\""+\
X " address=\"0x"+format(ar.adr+nb*ar.obj.addr_size,"08x")+"\""+\
X " module=\""+ar.obj.name+"_address.xml\"/>\n"
X res+="</node>\n"
X with open(self.name+"_address.xml","w") as fo:
X fo.write(res)
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/src/wb_block.py'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/src/wb_block.py'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/src/wb_block.py failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/src/wb_block.py': 'MD5 check failed'
) << \SHAR_EOF
d3503afb9434391979163b9d05ce8575 addr_gen_wb/src/wb_block.py
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/src/wb_block.py'` -ne 22159 && \
${echo} "restoration warning: size of 'addr_gen_wb/src/wb_block.py' is not 22159"
fi
fi
# ============= addr_gen_wb/src/addr_gen_wb.py ==============
if test ! -d 'addr_gen_wb/src'; then
mkdir 'addr_gen_wb/src'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/src."
else ${echo} "x - failed to create directory addr_gen_wb/src."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/src/addr_gen_wb.py'
then
${echo} "x - SKIPPING addr_gen_wb/src/addr_gen_wb.py (file already exists)"

else
${echo} "x - extracting addr_gen_wb/src/addr_gen_wb.py (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/src/addr_gen_wb.py' &&
#!/usr/bin/python3
"""
This is the script that generates the VHDL code needed to access
the registers in a hierarchical Wishbone-conencted system.
X
Written by Wojciech M. Zabolotny
(***@gmail.com or ***@ise.pw.edu.pl)
X
The code is published under LGPL V2 license
"""
import xml.etree.ElementTree as et
import wb_block as wb
import time
X
# As the version for generated code (HDL and SW)
# we take the 32-bit of the system time.
ver_id = int(time.time()) & 0xFFFFffff
X
sysdef=et.ElementTree(file="../example1.xml")
# We get the root element, and find the corresponding block
er=sysdef.getroot()
top_name=er.attrib["top"]
# Now we find the top block definition
X
# We should evaluate the address space requirements in each block
# In the first run, we calculate the space occupied by registers,
# but as blocks may be defined in different order, we also
# analyze the block dependencies.
X
# Create the list of blocks
for el in er.findall("block"):
X # Here we take each block and count registers inside
X # We also prepare the list of subblocks (of vectors of
X # subblocks)
X bn=el.attrib['name']
X if bn in wb.blocks:
X raise Exception("Duplicate definition of block: "+bn)
X bl = wb.wb_block(el)
X wb.blocks[bn] = bl
# Here we have everything, we could get from the first scan.
bl=wb.blocks[top_name]
bl.analyze()
for key,bl in wb.blocks.items():
X if bl.used:
X bl.gen_vhdl(ver_id)
# Now we generate the address tables
for key,bl in wb.blocks.items():
X if bl.used:
X bl.gen_ipbus_xml(ver_id)
X
X
X
X
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/src/addr_gen_wb.py'
eval "${shar_touch}") && \
chmod 0755 'addr_gen_wb/src/addr_gen_wb.py'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/src/addr_gen_wb.py failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/src/addr_gen_wb.py': 'MD5 check failed'
) << \SHAR_EOF
0d794f8c8354cc27cc99092076518f72 addr_gen_wb/src/addr_gen_wb.py
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/src/addr_gen_wb.py'` -ne 1524 && \
${echo} "restoration warning: size of 'addr_gen_wb/src/addr_gen_wb.py' is not 1524"
fi
fi
# ============= addr_gen_wb/test/prepare.sh ==============
if test ! -d 'addr_gen_wb/test'; then
mkdir 'addr_gen_wb/test'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/test."
else ${echo} "x - failed to create directory addr_gen_wb/test."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/prepare.sh'
then
${echo} "x - SKIPPING addr_gen_wb/test/prepare.sh (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/prepare.sh (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/prepare.sh' &&
#!/bin/bash
set -e
(
X git clone git://ohwr.org/hdl-core-lib/general-cores.git
X cd general-cores
X # I have done simply:
X # git checkout propose_master
X # but as general-cores may further evolve, and get incompatible
X # with my codes, here I get the particular commit:
X git checkout 3bbcf4a385999625bfdeac568410f248b017f57f
)
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/prepare.sh'
eval "${shar_touch}") && \
chmod 0755 'addr_gen_wb/test/prepare.sh'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/prepare.sh failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/prepare.sh': 'MD5 check failed'
) << \SHAR_EOF
4b11986e9e85e8d71bc978710240cb25 addr_gen_wb/test/prepare.sh
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/prepare.sh'` -ne 332 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/prepare.sh' is not 332"
fi
fi
# ============= addr_gen_wb/test/gen/dummy ==============
if test ! -d 'addr_gen_wb/test'; then
mkdir 'addr_gen_wb/test'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/test."
else ${echo} "x - failed to create directory addr_gen_wb/test."
exit 1
fi
fi
if test ! -d 'addr_gen_wb/test/gen'; then
mkdir 'addr_gen_wb/test/gen'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/test/gen."
else ${echo} "x - failed to create directory addr_gen_wb/test/gen."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/gen/dummy'
then
${echo} "x - SKIPPING addr_gen_wb/test/gen/dummy (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/gen/dummy (empty)"
'addr_gen_wb/test/gen/dummy' &&
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/gen/dummy'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/gen/dummy'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/gen/dummy failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/gen/dummy': 'MD5 check failed'
) << \SHAR_EOF
d41d8cd98f00b204e9800998ecf8427e addr_gen_wb/test/gen/dummy
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/gen/dummy'` -ne 0 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/gen/dummy' is not 0"
fi
fi
# ============= addr_gen_wb/test/example1.xml ==============
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/example1.xml'
then
${echo} "x - SKIPPING addr_gen_wb/test/example1.xml (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/example1.xml (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/example1.xml' &&
<sysdef top="MAIN">
X
<block name="SYS1">
X <creg name="CTRL" desc="Control register" stb="1" />
X <sreg name="STATUS" desc="Control register" ack="1" />
X <creg name="ENABLEs" desc="Link enable registers" reps="10"/>
</block>
X
<block name="MAIN">
X <subblock name="LINKS" type="SYS1" reps="5"/>
X <creg name="CTRL" desc="Control register">
X <field name="CLK_ENABLE" width="1"/>
X <field name="CLK_FREQ" width="4"/>
X <field name="PLL_RESET" width="1"/>
X </creg>
</block>
X
</sysdef>
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/example1.xml'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/example1.xml'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/example1.xml failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/example1.xml': 'MD5 check failed'
) << \SHAR_EOF
1cfe15b720d08faad4709cac8893bf8a addr_gen_wb/test/example1.xml
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/example1.xml'` -ne 490 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/example1.xml' is not 490"
fi
fi
# ============= addr_gen_wb/test/Makefile ==============
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/Makefile'
then
${echo} "x - SKIPPING addr_gen_wb/test/Makefile (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/Makefile (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/Makefile' &&
STD=standard
#STD=synopsys
VSTD=93c
ENTITY=wb_test_top_tb
# --unbuffered option must be added in the new GHDL
RUN_OPTIONS= --unbuffered --stop-time=3900ns --wave=${ENTITY}.ghw
#RUN_OPTIONS+= --trace-signals
#RUN_OPTIONS= --stop-time=290000ns
#RUN_OPTIONS= --wave=${ENTITY}.ghw
SOURCES = \
X general-cores/modules/genrams/genram_pkg.vhd \
X general-cores/modules/wishbone/wishbone_pkg.vhd \
X general-cores/modules/wishbone/wb_crossbar/xwb_crossbar.vhd \
X gen/SYS1_pkg.vhd \
X gen/SYS1_wb.vhd \
X hdl/sys1.vhd \
X gen/MAIN_pkg.vhd \
X gen/MAIN_wb.vhd \
X hdl/main.vhd \
X hdl/sim_wb_ctrl.vhd \
X hdl/wb_test_top.vhd \
X hdl/wb_test_top_tb.vhd \
X
OBJECTS=$(SOURCES:.vhd=.o)
X
%.o : %.vhd
X ghdl -a -g -C --std=${VSTD} --ieee=${STD} $<
# ghdl -a -g -C --workdir=comp --std=${VSTD} --ieee=${STD} $<
X
#--trace-signals --trace-processes
#RUN_OPTIONS=
#--trace-processes
all: show
show: ${ENTITY} ${ENTITY}.ghw
X gtkwave ${ENTITY}.ghw ${ENTITY}.sav
${ENTITY}: $(SOURCES:.vhd=.o)
# vhdlp -work fmf fmf/*.vhd
# ghdl -e -g --mb-comments --workdir=comp --std=${VSTD} -fexplicit --ieee=${STD} ${ENTITY}
X ghdl -e -g --mb-comments --std=${VSTD} -fexplicit --ieee=${STD} ${ENTITY}
${ENTITY}.ghw: ${ENTITY}
# ./${ENTITY} --wave=${ENTITY}.ghw ${RUN_OPTIONS} --stop-time=50000ns 2>&1 > res.txt
X ./${ENTITY} ${RUN_OPTIONS}
#> res.txt 2>&1
clean:
X rm -f comp/* *.o *.vcd *.ghw events* ${ENTITY}
X
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/Makefile'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/Makefile'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/Makefile failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/Makefile': 'MD5 check failed'
) << \SHAR_EOF
bc8557616262a55722632c06614d049a addr_gen_wb/test/Makefile
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/Makefile'` -ne 1375 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/Makefile' is not 1375"
fi
fi
# ============= addr_gen_wb/test/python/cbus.py ==============
if test ! -d 'addr_gen_wb/test/python'; then
mkdir 'addr_gen_wb/test/python'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/test/python."
else ${echo} "x - failed to create directory addr_gen_wb/test/python."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/python/cbus.py'
then
${echo} "x - SKIPPING addr_gen_wb/test/python/cbus.py (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/python/cbus.py (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/python/cbus.py' &&
#!/usr/bin/python3
# -*- coding: utf-8 -*-
X
def bus_write(adr,dana):
X cmd="W"+("%8.8x" % adr)+","+("%8.8x" % dana)+"\n"
X wrpip.write(cmd)
X wrpip.flush()
X s=rdpip.readline()
X if s.strip()=="ACK":
X return
X else:
X raise Exception("Wrong status returned:"+s.strip())
def bus_read(adr):
X cmd="R"+("%8.8x" % adr)+"\n"
X wrpip.write(cmd)
X wrpip.flush()
X s=rdpip.readline()
X if s.strip()=="ERR":
X raise Exception("Error status returned")
X return eval("0x"+s)
X
def bus_delay(time_ns):
X cmd="T"+("%8.8x" % time_ns)+"\n"
X wrpip.write(cmd)
X wrpip.flush()
print("Python controller ready. Start the simulation!\n")
wrpip=open("/tmp/wrpipe","w")
rdpip=open("/tmp/rdpipe","r")
X
import xml.etree.ElementTree as et
class cbus_obj(object):
X def __init__(self,adr,perm,mask):
X self.adr=adr
X self.can_read=False
X if perm.find("r")>=0:
X self.can_read=True
X self.can_write=False
X if perm.find("w")>=0:
X self.can_write=True
X #Now analyze mask
X if mask==0:
X self.mask = mask
X else:
X self.mask = mask
X #Find shift
X shift=0;
X while mask & 1 == 0:
X mask >>= 1
X shift+=1
X self.shift = shift
X def write(self,value):
X if not self.can_write:
X raise Exception("I can't write to this object")
X if self.mask==0:
X return bus_write(self.adr,value)
X else:
X prev=bus_read(self.adr)
X new_val=value << self.shift
X if (new_val & self.mask) != new_val:
X raise Exception("Attempt to write outside the mask!")
X prev |= self.mask
X prev ^= self.mask
X prev |= new_val
X return bus_write(self.adr, prev)
X
X def read(self):
X if not self.can_read:
X raise Exception("I can't read this object")
X if self.mask==0:
X return bus_read(self.adr)
X else:
X val = bus_read(self.adr)
X val &= self.mask
X val >>= self.shift
X return val
X
def cbus_read_nodes(addr_directory,address_table_file,base_name="",base_addr=0,nodes={}):
X plik1=et.ElementTree(file=addr_directory+'/'+address_table_file)
X print("Reading file: "+address_table_file)
X #Take the root element
X er=plik1.getroot()
X #It should be "node"
X if er.tag != "node":
X raise Exception("Wrong type of the root element!")
X #Scan child nodes
X for el in er.findall("node"):
X print(el.tag)
X print(el.attrib)
X if base_name != "":
X name = base_name+"."
X else:
X name = ""
X name += el.attrib['id']
X adr = base_addr+int(el.attrib['address'],16)
X if 'module' in el.attrib:
X #This is a nested module
X cbus_read_nodes(addr_directory,el.get('module'),name,adr,nodes)
X else:
X perm = el.attrib['permission']
X mask = int(el.get('mask','0x0'),16)
X # Now we need to check if there are bitfields inside...
X for bf in el.findall("node"):
X mask = int(bf.get('mask','0x0'),16)
X bfname=name+"."+bf.get('id')
X nodes[bfname]=cbus_obj(adr,perm,mask)
X nodes[name]=cbus_obj(adr,perm,mask)
X return nodes
X
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/python/cbus.py'
eval "${shar_touch}") && \
chmod 0755 'addr_gen_wb/test/python/cbus.py'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/python/cbus.py failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/python/cbus.py': 'MD5 check failed'
) << \SHAR_EOF
bbd0dd8747cb35f10a367af4e0d9f02c addr_gen_wb/test/python/cbus.py
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/python/cbus.py'` -ne 3201 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/python/cbus.py' is not 3201"
fi
fi
# ============= addr_gen_wb/test/python/wb_test.py ==============
if test ! -d 'addr_gen_wb/test/python'; then
mkdir 'addr_gen_wb/test/python'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/test/python."
else ${echo} "x - failed to create directory addr_gen_wb/test/python."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/python/wb_test.py'
then
${echo} "x - SKIPPING addr_gen_wb/test/python/wb_test.py (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/python/wb_test.py (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/python/wb_test.py' &&
#!/usr/bin/python3
import cbus
nodes=cbus.cbus_read_nodes('gen','MAIN_address.xml')
cbus.bus_delay(100)
print("Test the ID")
print ("ID read:"+ hex(nodes['ID'].read()))
print ("VER read:"+ hex(nodes['VER'].read()))
cbus.bus_delay(250)
print("LINKS1 ID read:"+hex(nodes['LINKS[0].ID'].read()))
print("LINKS1 VER read:"+hex(nodes['LINKS[0].VER'].read()))
cbus.bus_delay(250)
print("LINKS1 STATUS read:"+hex(nodes['LINKS[0].STATUS'].read()))
cbus.bus_delay(250)
print("LINKS1 CTRL write")
nodes['LINKS[0].CTRL'].write(0xdce432)
cbus.bus_delay(250)
print("LINKS4 STATUS read:"+hex(nodes['LINKS[4].STATUS'].read()))
cbus.bus_delay(250)
print("LINKS4 CTRL write")
nodes['LINKS[4].CTRL'].write(0x35678)
print("Now we test bitfields")
nodes['CTRL.CLK_ENABLE'].write(1)
cbus.bus_delay(30)
nodes['CTRL.CLK_FREQ'].write(0xc)
cbus.bus_delay(30)
nodes['CTRL.PLL_RESET'].write(1)
cbus.bus_delay(30)
nodes['CTRL.CLK_ENABLE'].write(0)
cbus.bus_delay(30)
nodes['CTRL.CLK_FREQ'].write(0x5)
cbus.bus_delay(30)
nodes['CTRL.PLL_RESET'].write(0)
cbus.bus_delay(3000)
X
X
X
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/python/wb_test.py'
eval "${shar_touch}") && \
chmod 0755 'addr_gen_wb/test/python/wb_test.py'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/python/wb_test.py failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/python/wb_test.py': 'MD5 check failed'
) << \SHAR_EOF
ee4f31aaf2ef506ab7808101f883d58f addr_gen_wb/test/python/wb_test.py
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/python/wb_test.py'` -ne 1048 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/python/wb_test.py' is not 1048"
fi
fi
# ============= addr_gen_wb/test/wb_test.sh ==============
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/wb_test.sh'
then
${echo} "x - SKIPPING addr_gen_wb/test/wb_test.sh (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/wb_test.sh (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/wb_test.sh' &&
#!/bin/bash
set -e
rm -f /tmp/rdpipe /tmp/wrpipe
# Create the named pipes
mknod /tmp/rdpipe p
mknod /tmp/wrpipe p
# Run the python script in the other xterm
xterm -e "python3 python/wb_test.py; echo 'press ENTER'; read" &
make
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/wb_test.sh'
eval "${shar_touch}") && \
chmod 0755 'addr_gen_wb/test/wb_test.sh'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/wb_test.sh failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/wb_test.sh': 'MD5 check failed'
) << \SHAR_EOF
447dcc83ab6acdf55bf8e0c801aa3b1a addr_gen_wb/test/wb_test.sh
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/wb_test.sh'` -ne 227 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/wb_test.sh' is not 227"
fi
fi
# ============= addr_gen_wb/test/generate.sh ==============
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/generate.sh'
then
${echo} "x - SKIPPING addr_gen_wb/test/generate.sh (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/generate.sh (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/generate.sh' &&
#!/bin/bash
set -e
( cd gen ; ../../src/addr_gen_wb.py )
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/generate.sh'
eval "${shar_touch}") && \
chmod 0755 'addr_gen_wb/test/generate.sh'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/generate.sh failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/generate.sh': 'MD5 check failed'
) << \SHAR_EOF
d1dc2469bb9806b5a9a2c23902f01e13 addr_gen_wb/test/generate.sh
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/generate.sh'` -ne 57 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/generate.sh' is not 57"
fi
fi
# ============= addr_gen_wb/test/hdl/wb_test_top_tb.vhd ==============
if test ! -d 'addr_gen_wb/test/hdl'; then
mkdir 'addr_gen_wb/test/hdl'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/test/hdl."
else ${echo} "x - failed to create directory addr_gen_wb/test/hdl."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/hdl/wb_test_top_tb.vhd'
then
${echo} "x - SKIPPING addr_gen_wb/test/hdl/wb_test_top_tb.vhd (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/hdl/wb_test_top_tb.vhd (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/hdl/wb_test_top_tb.vhd' &&
-------------------------------------------------------------------------------
-- Title : Testbench for design "wb_test_top"
-- Project :
-------------------------------------------------------------------------------
-- File : wb_test_top_tb.vhd
-- Author : Wojciech Zabołotny <***@wzab.nasz.dom>
-- Company :
-- Created : 2018-11-11
-- Last update: 2018-11-11
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description:
-------------------------------------------------------------------------------
-- Copyright (c) 2018
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2018-11-11 1.0 wzab Created
-------------------------------------------------------------------------------
X
library ieee;
use ieee.std_logic_1164.all;
X
-------------------------------------------------------------------------------
X
entity wb_test_top_tb is
X
end entity wb_test_top_tb;
X
-------------------------------------------------------------------------------
X
architecture test of wb_test_top_tb is
X
X -- component generics
X constant rdpipename : string := "/tmp/rdpipe";
X constant wrpipename : string := "/tmp/wrpipe";
X
X -- component ports
X signal rst_i : std_logic := '1';
X signal clk_sys_i : std_logic;
X
X -- clock
X signal Clk : std_logic := '1';
X
begin -- architecture test
X
X clk_sys_i <= clk;
X -- component instantiation
X DUT: entity work.wb_test_top
X generic map (
X rdpipename => rdpipename,
X wrpipename => wrpipename)
X port map (
X rst_i => rst_i,
X clk_sys_i => clk_sys_i);
X
X -- clock generation
X Clk <= not Clk after 10 ns;
X
X -- waveform generation
X WaveGen_Proc: process
X begin
X -- insert signal assignments here
X rst_i <= '1';
X wait until Clk = '1';
X wait until Clk = '0';
X wait until Clk = '1';
X wait for 5 ns;
X rst_i <= '0';
X wait;
X end process WaveGen_Proc;
X
X
X
end architecture test;
X
-------------------------------------------------------------------------------
X
configuration wb_test_top_tb_test_cfg of wb_test_top_tb is
X for test
X end for;
end wb_test_top_tb_test_cfg;
X
-------------------------------------------------------------------------------
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/hdl/wb_test_top_tb.vhd'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/hdl/wb_test_top_tb.vhd'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/hdl/wb_test_top_tb.vhd failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/hdl/wb_test_top_tb.vhd': 'MD5 check failed'
) << \SHAR_EOF
2a75f74386e44ca591b8a2bc0e50334e addr_gen_wb/test/hdl/wb_test_top_tb.vhd
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/hdl/wb_test_top_tb.vhd'` -ne 2340 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/hdl/wb_test_top_tb.vhd' is not 2340"
fi
fi
# ============= addr_gen_wb/test/hdl/main.vhd ==============
if test ! -d 'addr_gen_wb/test/hdl'; then
mkdir 'addr_gen_wb/test/hdl'
if test $? -eq 0
then ${echo} "x - created directory addr_gen_wb/test/hdl."
else ${echo} "x - failed to create directory addr_gen_wb/test/hdl."
exit 1
fi
fi
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/hdl/main.vhd'
then
${echo} "x - SKIPPING addr_gen_wb/test/hdl/main.vhd (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/hdl/main.vhd (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/hdl/main.vhd' &&
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.MAIN_wb_pkg.all;
X
entity main is
X
X port (
X rst_n_i : in std_logic;
X clk_sys_i : in std_logic;
X wb_s_in : in t_wishbone_slave_in;
X wb_s_out : out t_wishbone_slave_out
X );
X
end entity main;
X
architecture rtl of main is
X signal LINKS_wb_m_o : t_wishbone_master_out_array(0 to 4);
X signal LINKS_wb_m_i : t_wishbone_master_in_array(0 to 4);
X signal CTRL_o : t_CTRL;
begin -- architecture rtl
X
X MAIN_wb_1: entity work.MAIN_wb
X port map (
X slave_i => wb_s_in,
X slave_o => wb_s_out,
X LINKS_wb_m_o => LINKS_wb_m_o,
X LINKS_wb_m_i => LINKS_wb_m_i,
X CTRL_o => CTRL_o,
X rst_n_i => rst_n_i,
X clk_sys_i => clk_sys_i);
X
X gl1: for i in 0 to 4 generate
X
X sys1_1: entity work.sys1
X port map (
X rst_n_i => rst_n_i,
X clk_sys_i => clk_sys_i,
X wb_s_in => LINKS_wb_m_o(i),
X wb_s_out => LINKS_wb_m_i(i));
X
X end generate gl1;
X
X
end architecture rtl;
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/hdl/main.vhd'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/hdl/main.vhd'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/hdl/main.vhd failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/hdl/main.vhd': 'MD5 check failed'
) << \SHAR_EOF
6d6c28017b5ab3da1a766d9323507397 addr_gen_wb/test/hdl/main.vhd
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/hdl/main.vhd'` -ne 1087 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/hdl/main.vhd' is not 1087"
fi
fi
# ============= addr_gen_wb/test/hdl/sim_wb_ctrl.vhd ==============
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/hdl/sim_wb_ctrl.vhd'
then
${echo} "x - SKIPPING addr_gen_wb/test/hdl/sim_wb_ctrl.vhd (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/hdl/sim_wb_ctrl.vhd (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/hdl/sim_wb_ctrl.vhd' &&
-- Code used to implement the emulated bus
-- according to method publicly disclosed by W.M.Zabolotny in 2007
-- Usenet alt.sources "Bus controller model for VHDL & Python cosimulation"
X
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.wishbone_pkg.all;
library work;
X
entity sim_wb_ctrl is
X
X generic (
X rdpipename : string := "rdpipe";
X wrpipename : string := "wrpipe"
X );
X
X port (
X wb_m_out : out t_wishbone_master_out;
X wb_m_in : in t_wishbone_master_in;
X clk_sys_i : in std_logic
X );
X
end sim_wb_ctrl;
X
architecture simul of sim_wb_ctrl is
X
X constant addrwidth, datawidth : integer := 32;
X
begin -- simul
X
X
X
X process
X
X file write_pipe : text;
X file read_pipe : text;
X variable code : character;
X variable db_line : line;
X variable rd_line : line;
X variable wr_line : line;
X variable sync_with_slope : boolean := false;
X variable status : boolean := false;
X
X procedure read_hex_stlv (
X variable fline : inout line;
X constant nbits : integer;
X variable res : out std_logic_vector) is
X
X variable tmp : std_logic_vector((nbits+3) downto 0) := (others => '0');
X variable c : character;
X variable npos, nchars : integer;
X begin -- readhex
X nchars := (nbits+3)/4; -- number of hex chars to read
X for i in nchars-1 downto 0 loop
X npos := i*4+3;
X read (fline, c);
X case c is
X when '0' =>
X tmp(npos downto npos-3) := "0000";
X when '1' =>
X tmp(npos downto npos-3) := "0001";
X when '2' =>
X tmp(npos downto npos-3) := "0010";
X when '3' =>
X tmp(npos downto npos-3) := "0011";
X when '4' =>
X tmp(npos downto npos-3) := "0100";
X when '5' =>
X tmp(npos downto npos-3) := "0101";
X when '6' =>
X tmp(npos downto npos-3) := "0110";
X when '7' =>
X tmp(npos downto npos-3) := "0111";
X when '8' =>
X tmp(npos downto npos-3) := "1000";
X when '9' =>
X tmp(npos downto npos-3) := "1001";
X when 'a' =>
X tmp(npos downto npos-3) := "1010";
X when 'A' =>
X tmp(npos downto npos-3) := "1010";
X when 'b' =>
X tmp(npos downto npos-3) := "1011";
X when 'B' =>
X tmp(npos downto npos-3) := "1011";
X when 'c' =>
X tmp(npos downto npos-3) := "1100";
X when 'C' =>
X tmp(npos downto npos-3) := "1100";
X when 'd' =>
X tmp(npos downto npos-3) := "1101";
X when 'D' =>
X tmp(npos downto npos-3) := "1101";
X when 'e' =>
X tmp(npos downto npos-3) := "1110";
X when 'E' =>
X tmp(npos downto npos-3) := "1110";
X when 'f' =>
X tmp(npos downto npos-3) := "1111";
X when 'F' =>
X tmp(npos downto npos-3) := "1111";
X when others =>
X assert(false)
X report "Error: wrong separator in the write command" severity error;
X end case;
X end loop; -- i
X res := tmp((nbits-1) downto 0);
X end read_hex_stlv;
X
X procedure write_stlv_hex2 (
X res : inout line;
X constant vec : std_logic_vector) is
X variable nibble : integer;
X constant hexdigs : string := "0123456789abcdef";
X begin -- stlv2hex
X nibble := 0;
X if vec'left <= vec'right then
X for i in vec'left to vec'right loop
X if vec(i) = '1' then
X nibble := nibble + 2**(i-vec'left);
X end if;
X end loop; -- i
X else
X for i in vec'right to vec'left loop
X if vec(i) = '1' then
X nibble := nibble + 2**(i-vec'right);
X end if;
X end loop; -- i
X end if;
X write(res, nibble);
X end write_stlv_hex2;
X
X procedure write_stlv_hex (
X res : inout line;
X constant vec : std_logic_vector) is
X variable nibble : integer;
X variable pos : integer;
X constant hexdigs : string := "0123456789abcdef";
X begin -- stlv2hex
X nibble := 1;
X if vec'right <= vec'left then
X for i in vec'left downto vec'right loop
X -- calculate the nibbles
X pos := i mod 4;
X if vec(i) = '1' then
X nibble := nibble + 2**(pos);
X end if;
X if pos = 0 then
X write(res, hexdigs(nibble));
X nibble := 1;
X end if;
X end loop; -- i
X else
X for i in vec'right downto vec'left loop
X pos := i mod 4;
X if vec(i) = '1' then
X nibble := nibble + 2**(pos);
X end if;
X if pos = 0 then
X write(res, hexdigs(nibble));
X nibble := 1;
X end if;
X end loop; -- i
X end if;
X end write_stlv_hex;
X
X procedure bus_read (
X variable address : in std_logic_vector((addrwidth-1) downto 0);
X variable data : out std_logic_vector((datawidth-1) downto 0);
X variable status : out boolean
X ) is
X begin -- ipbus_read
X if sync_with_slope = false then
X wait until rising_edge(clk_sys_i);
X sync_with_slope := true;
X end if;
X wb_m_out.adr <= address;
X wb_m_out.we <= '0';
X wb_m_out.stb <= '1';
X wb_m_out.cyc <= '1';
X wb_m_out.sel <= (others => '0');
X lr1 : loop
X wait until rising_edge(clk_sys_i);
X if wb_m_in.ack = '1' then
X data := wb_m_in.dat;
X status := true;
X exit lr1;
X end if;
X if wb_m_in.err = '1' then
X data := (others => '0');
X status := false;
X exit lr1;
X end if;
X end loop;
X wb_m_out.stb <= '0';
X wb_m_out.cyc <= '0';
X lr2 : loop
X wait until rising_edge(clk_sys_i);
X if (wb_m_in.ack = '0') and
X (wb_m_in.err = '0')and
X (wb_m_in.rty = '0')
X then
X exit lr2;
X end if;
X end loop;
X end bus_read;
X
X procedure bus_write (
X variable address : in std_logic_vector((addrwidth-1) downto 0);
X variable data : in std_logic_vector((datawidth-1) downto 0);
X variable status : out boolean
X ) is
X begin
X --report "Started bus_write" severity note;
X if sync_with_slope = false then
X wait until rising_edge(clk_sys_i);
X sync_with_slope := true;
X end if;
X wb_m_out.adr <= address;
X wb_m_out.dat <= data;
X wb_m_out.we <= '1';
X wb_m_out.stb <= '1';
X wb_m_out.cyc <= '1';
X wb_m_out.sel <= (others => '1');
X lw1 : loop
X wait until rising_edge(clk_sys_i);
X if wb_m_in.ack = '1' then
X status := true;
X exit lw1;
X end if;
X if wb_m_in.err = '1' then
X status := false;
X exit lw1;
X end if;
X end loop;
X wb_m_out.stb <= '0';
X wb_m_out.cyc <= '0';
X wb_m_out.we <= '0';
X lw2 : loop
X wait until rising_edge(clk_sys_i);
X if (wb_m_in.ack = '0') and
X (wb_m_in.err = '0')and
X (wb_m_in.rty = '0')
X then
X exit lw2;
X end if;
X end loop;
X end bus_write;
X
X variable delay : integer;
X variable data : std_logic_vector(31 downto 0);
X variable address : std_logic_vector(31 downto 0);
X
X begin -- process
X file_open(write_pipe, wrpipename, read_mode);
X file_open(read_pipe, rdpipename, write_mode);
X wb_m_out.dat <= (others => '0');
X wb_m_out.adr <= (others => '0');
X wb_m_out.sel <= (others => '0');
X wb_m_out.cyc <= '0';
X wb_m_out.stb <= '0';
X wb_m_out.we <= '0';
X
X while not endfile(write_pipe) loop
X -- We read the command from the wrpipe
X readline (write_pipe, rd_line);
X -- Analyze the line (Waddress,data)
X read (rd_line, code);
X case code is
X when 'W' =>
X read_hex_stlv(rd_line, addrwidth, address);
X read (rd_line, code);
X if code /= ',' then
X assert(false)
X report "Error: wrong separator in the write command" severity error;
X end if;
X read_hex_stlv(rd_line, datawidth, data);
X bus_write(address, data, status);
X if status then
X write(wr_line, string'("ACK"));
X else
X write(wr_line, string'("ERR"));
X end if;
X writeline(read_pipe, wr_line);
X -- If you are using VHDL-2008, you may uncomment
X -- the flush command below, and run GHDL without
X -- "--unbuffered" option
X --flush(read_pipe);
X when 'R' =>
X read_hex_stlv(rd_line, addrwidth, address);
X bus_read(address, data, status);
X if status then
X write_stlv_hex(wr_line, data);
X else
X write(wr_line, string'("ERR"));
X end if;
X writeline(read_pipe, wr_line);
X -- If you are using VHDL-2008, you may uncomment
X -- the flush command below, and run GHDL without
X -- "--unbuffered" option
X --flush(read_pipe);
X when 'T' =>
X read_hex_stlv(rd_line, 32, data);
X delay := to_integer(unsigned(data));
X wait for delay * 1 ns;
X sync_with_slope := false;
X when others =>
X assert(false)
X report "Error: wrong character at the begining of the line" severity error;
X end case;
X end loop;
X wait;
X end process;
X
X
end simul;
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/hdl/sim_wb_ctrl.vhd'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/hdl/sim_wb_ctrl.vhd'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/hdl/sim_wb_ctrl.vhd failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/hdl/sim_wb_ctrl.vhd': 'MD5 check failed'
) << \SHAR_EOF
629d2a52f09bdc92a3f70e0fd00676b3 addr_gen_wb/test/hdl/sim_wb_ctrl.vhd
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/hdl/sim_wb_ctrl.vhd'` -ne 9581 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/hdl/sim_wb_ctrl.vhd' is not 9581"
fi
fi
# ============= addr_gen_wb/test/hdl/wb_test_top.vhd ==============
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/hdl/wb_test_top.vhd'
then
${echo} "x - SKIPPING addr_gen_wb/test/hdl/wb_test_top.vhd (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/hdl/wb_test_top.vhd (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/hdl/wb_test_top.vhd' &&
-- Code used to implement the emulated bus
-- according to method publicly disclosed by W.M.Zabolotny in 2007
-- Usenet alt.sources "Bus controller model for VHDL & Python cosimulation"
X
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use work.wishbone_pkg.all;
library work;
X
entity wb_test_top is
X
X generic (
X rdpipename : string := "rdpipe";
X wrpipename : string := "wrpipe"
X );
X
X port (
X rst_i : in std_logic;
X clk_sys_i : in std_logic
X );
X
end wb_test_top;
X
architecture simul of wb_test_top is
X
X constant addrwidth, datawidth : integer := 32;
X
X signal wb_m_out : t_wishbone_master_out := c_DUMMY_WB_MASTER_OUT;
X signal wb_m_in : t_wishbone_master_in := c_DUMMY_WB_MASTER_IN;
X
X signal rst_n_i : std_logic;
X
begin -- simul
X
X rst_n_i <= not rst_i;
X
X sim_wb_ctrl_1: entity work.sim_wb_ctrl
X generic map (
X rdpipename => rdpipename,
X wrpipename => wrpipename)
X port map (
X wb_m_out => wb_m_out,
X wb_m_in => wb_m_in,
X clk_sys_i => clk_sys_i);
X
X main_1: entity work.main
X port map (
X rst_n_i => rst_n_i,
X clk_sys_i => clk_sys_i,
X wb_s_in => wb_m_out,
X wb_s_out => wb_m_in);
X
end simul;
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/hdl/wb_test_top.vhd'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/hdl/wb_test_top.vhd'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/hdl/wb_test_top.vhd failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/hdl/wb_test_top.vhd': 'MD5 check failed'
) << \SHAR_EOF
de13cb3f2eab396cf041423754ff3c53 addr_gen_wb/test/hdl/wb_test_top.vhd
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/hdl/wb_test_top.vhd'` -ne 1215 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/hdl/wb_test_top.vhd' is not 1215"
fi
fi
# ============= addr_gen_wb/test/hdl/sys1.vhd ==============
if test -n "${keep_file}" && test -f 'addr_gen_wb/test/hdl/sys1.vhd'
then
${echo} "x - SKIPPING addr_gen_wb/test/hdl/sys1.vhd (file already exists)"

else
${echo} "x - extracting addr_gen_wb/test/hdl/sys1.vhd (text)"
sed 's/^X//' << 'SHAR_EOF' > 'addr_gen_wb/test/hdl/sys1.vhd' &&
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.wishbone_pkg.all;
use work.sys1_wb_pkg.all;
X
entity sys1 is
X
X port (
X rst_n_i : in std_logic;
X clk_sys_i : in std_logic;
X wb_s_in : in t_wishbone_slave_in;
X wb_s_out : out t_wishbone_slave_out
X );
X
end entity sys1;
X
architecture rtl of sys1 is
X
X signal slave_i : t_wishbone_slave_in;
X signal slave_o : t_wishbone_slave_out;
X signal CTRL_o : t_CTRL;
X signal CTRL_o_stb : std_logic;
X signal STATUS_i : t_STATUS;
X signal STATUS_i_ack : std_logic;
X signal ENABLEs_o : t_ENABLEs_array;
X
begin -- architecture rtl
X
X SYS1_wb_1: entity work.SYS1_wb
X port map (
X slave_i => wb_s_in,
X slave_o => wb_s_out,
X CTRL_o => CTRL_o,
X CTRL_o_stb => CTRL_o_stb,
X STATUS_i => STATUS_i,
X STATUS_i_ack => STATUS_i_ack,
X ENABLEs_o => ENABLEs_o,
X rst_n_i => rst_n_i,
X clk_sys_i => clk_sys_i);
X
end architecture rtl;
SHAR_EOF
(set 20 18 11 18 00 18 48 'addr_gen_wb/test/hdl/sys1.vhd'
eval "${shar_touch}") && \
chmod 0644 'addr_gen_wb/test/hdl/sys1.vhd'
if test $? -ne 0
then ${echo} "restore of addr_gen_wb/test/hdl/sys1.vhd failed"
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'addr_gen_wb/test/hdl/sys1.vhd': 'MD5 check failed'
) << \SHAR_EOF
ca4ff3f903c3346812f215e57b49dc53 addr_gen_wb/test/hdl/sys1.vhd
SHAR_EOF

else
test `LC_ALL=C wc -c < 'addr_gen_wb/test/hdl/sys1.vhd'` -ne 992 && \
${echo} "restoration warning: size of 'addr_gen_wb/test/hdl/sys1.vhd' is not 992"
fi
fi
if rm -fr ${lock_dir}
then ${echo} "x - removed lock directory ${lock_dir}."
else ${echo} "x - failed to remove lock directory ${lock_dir}."
exit 1
fi
exit 0
w***@gmail.com
2018-11-17 23:27:57 UTC
Permalink
The maintained version of that code is available in the github repository: https://github.com/wzab/addr_gen_wb

Regards,
Wojtek

Loading...