#! /usr/bin/python
# $Id: prxconfig.py 7 2005-02-11 12:02:41Z phil $
#
# Generate a Pulser Receiver sequence register array, populate with random values and write out to VHDL
#

from random import randrange

# Useful functions

def truefalse():
    if randrange(0,2) == 0:
        return False
    else:
        return True

def tobin(x, count=8):
    return "".join(map(lambda y:str((x>>y)&1), range(count-1, -1, -1)))

def vhex(S):
    H = hex(S)[2:]
    L = len (H)
    if L < 8:
        return 'X"' + '0' * (8 - L) + H + '"'
    else:
        return 'X"' + H + '"'


# Global Configuration

class PRxGlobal:
    pass

G = PRxGlobal()

# Pulse-echo mode = True, Through-mode = False 

G.PulseEchoMode = [1,1,1,1,1,1,1,1]

# Trigger from external source

G.ExternalTrigger = 1

# Enable High Voltage

G.HighVoltageEnable = 1 

# Set High Voltage

G.HighVoltage = 2048 # 0-4095

# Sequence Table Configuration

class SequenceTableItem:
    pass

#S.SequenceActive = 1
#S.ReceiveChannel = 0 # 0-7
#S.TransmitChannels = [1,0,0,0,0,0,0,0] # n-of-8
#S.ExternalTCG = 0
#S.FineGain = 0 # 0-4095
#S.FrontendLowPass = 0 # 0-7
#S.FrontendHighPass = 0 # 0-7
#S.BackendLowPass = [1,0,0,0,0,0,0,0] # n-of-8
#S.BackendHighPass = [1,0,0,0,0,0,0,0] # n-of-8
#S.CoarseGain = 0 # 0-3
#S.InputImpedance = [1,0,0,0] # 1-of-4
#S.FineDelay = 0 # 0-255
#S.PulseWidth = 0 # 0-65535
#S.PreTriggerTime = 0 # 0-65535
#S.RepetitionRate = 0 # 0-2^32

# Create a random sequence table of 32 entries

ST=[]

for i in range(0,32):
    S = SequenceTableItem()
    S.SequenceActive = randrange(0,2)
    S.ExternalTCG = randrange(0,2)
    S.ReceiveChannel = randrange(0,8)
    S.FineGain = randrange(0,4096)
    S.FrontendLowPass = randrange(0,8)
    S.FrontendHighPass = randrange(0,8)
    S.CoarseGain = randrange(0,4)
    S.FineDelay = randrange(0,256)
    S.PulseWidth = randrange(0,65536)
    S.PreTriggerTime = randrange(0,65536)
    # For RepRate don't use the full 32 bits as it will never (?) be used and causes warnings about python longs
    S.RepetitionRate = randrange(0,pow(2,31))
    S.TransmitChannels = []
    S.BackendLowPass = []
    S.BackendHighPass = []
    for j in range(0,8):
        S.TransmitChannels.append(randrange(0,2))
        S.BackendLowPass.append(randrange(0,2))
        S.BackendHighPass.append(randrange(0,2))
    S.InputImpedance = [0,0,0,0]
    InputImpedance = randrange(0,4)
    S.InputImpedance[InputImpedance]=1
    ST.append(S)

# Assemble the Global Configuration word

Memblock32=[0,0,0] # Three dummy registers for Check, ID, and Command / Status

M = G.HighVoltage | ( G.HighVoltageEnable << 15 ) | ( G.ExternalTrigger << 16 )

G.PulseEchoMode.reverse()

for i in range (0,8):
    M = M | ((G.PulseEchoMode[i] << i) << 24 )

Memblock32.append(M)
    
# Loop through the sequence table and convert to hex

for S in ST:
    # Word 0
    M = ( S.ReceiveChannel << 16 ) | ( S.SequenceActive << 31 )
    S.TransmitChannels.reverse()
    for i in range (0,8):
        M = M | (S.TransmitChannels[i] << i)
    Memblock32.append(M)
    # Word 1
    M = S.FineGain | (S.ExternalTCG << 31)
    Memblock32.append(M)
    # Word 2
    M = (S.FrontendLowPass << 16) | (S.FrontendHighPass << 24);
    for i in range (0,8):
        M = M | (S.BackendLowPass[i] << i)
    for i in range (0,8):
        M = M | (S.BackendHighPass[i] << (i + 8))
    Memblock32.append(M)
    # Word 3
    M = (S.CoarseGain << 8)
    for i in range (0,4):
        M = M | (S.InputImpedance[i] << i)  
    Memblock32.append(M)
    # Word 4  
    M = S.FineDelay
    Memblock32.append(M)
    # Word 5
    M = S.PulseWidth
    Memblock32.append(M)
    # Word 6
    M = S.PreTriggerTime
    Memblock32.append(M)
    # Word 7
    M = S.RepetitionRate
    Memblock32.append(M)

# Iterate through the register block and write a VHDL file 

print 'library ieee;'
print 'use ieee.std_logic_1164.all;'
print 'use ieee.std_logic_unsigned.all;'
print 'entity prxregs is'
print '  port ('
print '    clk : in std_logic;'
print '    en  : in std_logic;'
print '    addr: in std_logic_vector(9 downto 0);'
print '    data: out std_logic_vector(31 downto 0)'
print '  );'
print 'end prxregs;'
print 'architecture synchronous of prxregs is'
print '  type reg_rom is array(0 to 259) of std_logic_vector(31 downto 0);'
print '  constant REGROM : reg_rom :='
print '('

bc=0
for M in Memblock32:
    bc=bc+1
    print vhex(M),
    if bc != len(Memblock32):
        print ','

print ');'
print 'begin'
print '  process (clk)'
print '    begin'
print '      if rising_edge(clk) then'
print "        if (en = '1') then"
print '          data <= REGROM(conv_integer(addr));'
print '        end if;'
print '      end if;'
print '  end process;'
print 'end architecture synchronous;'
 

