1 |
2 |
wzab |
#!/usr/bin/python
|
2 |
|
|
#
|
3 |
|
|
# This Python script generates the input patterns for the sorter
|
4 |
|
|
# It also generates the sys_config.vhd file with constants
|
5 |
|
|
# describing structure of data records
|
6 |
|
|
#
|
7 |
|
|
# You can customize constants below
|
8 |
|
|
key_width = 8 # Width of the key part of the record
|
9 |
|
|
pay_width = 4 # Width of the payload part of the record
|
10 |
|
|
max_dist = 63 # Maximum distance between unsorted records
|
11 |
|
|
seq_len = 2000 # Length of the generated sequence
|
12 |
|
|
sort_debug = "true" #uncomment this, or the next line
|
13 |
|
|
sort_debug = "false" #alwayse set sort_debug to false for synthesis!
|
14 |
|
|
#
|
15 |
7 |
wzab |
max_key_mask = (1<<key_width)-1 #Constant used for modulo operations on keys
|
16 |
2 |
wzab |
# The algorithm is very simple - we just generate the sequence
|
17 |
|
|
# of records with continuously increasing key numbers
|
18 |
|
|
# Then we increase the key number in each record by the random
|
19 |
|
|
# number, taken from the range: [0,max_dist]
|
20 |
|
|
import math
|
21 |
|
|
import sys
|
22 |
|
|
# calculate necessary amount of levels in the sorter
|
23 |
|
|
sys_nlevels=1
|
24 |
|
|
nrec=4
|
25 |
|
|
while nrec<max_dist+1:
|
26 |
|
|
sys_nlevels+=1
|
27 |
|
|
nrec*=2
|
28 |
|
|
# Sorter capacity and sorter latency is equal to nrec-1
|
29 |
|
|
latency=nrec-1
|
30 |
|
|
# When checking if the sorter key width is sufficient, we must
|
31 |
|
|
# consider, that in the worst key we may need to compare
|
32 |
|
|
# samples with keys differing by latency+max_dist
|
33 |
|
|
#
|
34 |
|
|
# Check if the settings are correct
|
35 |
7 |
wzab |
if max_dist+latency > max_key_mask:
|
36 |
2 |
wzab |
print "Too high maximum distance between unsorted records"
|
37 |
|
|
print "for defined width of the sort key. Please increase"
|
38 |
|
|
print "the key_width value in the sort_test_gen.py file!"
|
39 |
|
|
sys.exit(1)
|
40 |
|
|
# Then we prepare the VHDL file with system configuration
|
41 |
|
|
sc=open('src/sys_config.vhd','w')
|
42 |
|
|
l="library ieee;\n"
|
43 |
|
|
l+="use ieee.std_logic_1164.all;\n"
|
44 |
|
|
l+="library work;\n"
|
45 |
|
|
l+="package sys_config is\n"
|
46 |
|
|
l+=" constant SORT_DEBUG : boolean :="+sort_debug+";\n"
|
47 |
|
|
l+=" constant SYS_NLEVELS : integer :="+str(sys_nlevels)+";\n"
|
48 |
|
|
l+=" constant DATA_REC_SORT_KEY_WIDTH : integer :="+str(key_width)+";\n"
|
49 |
|
|
l+=" constant DATA_REC_PAYLOAD_WIDTH : integer :="+str(pay_width)+";\n"
|
50 |
|
|
l+="end sys_config;\n"
|
51 |
|
|
sc.write(l)
|
52 |
|
|
sc.close()
|
53 |
|
|
# Generate the input patterns
|
54 |
|
|
fo=open('events.in','w')
|
55 |
|
|
t=range(1,seq_len+1)
|
56 |
|
|
import random
|
57 |
|
|
r=random.Random()
|
58 |
|
|
r.seed()
|
59 |
|
|
t2=[i+r.randint(0,max_dist) for i in t]
|
60 |
|
|
# Now let's prepare the input events:
|
61 |
|
|
key_format="{0:0"+str(key_width)+"b}"
|
62 |
|
|
pay_format="{0:0"+str(pay_width)+"b}"
|
63 |
7 |
wzab |
max_key=0
|
64 |
2 |
wzab |
for i in t2:
|
65 |
|
|
j = i & ((1<<key_width)-1) #Truncate the key to the set width
|
66 |
7 |
wzab |
l = "0 " + key_format.format(j) + " " + pay_format.format(0)
|
67 |
|
|
#Adjust the maximum key
|
68 |
|
|
if (j+max_key_mask+1 - max_key) & max_key_mask < (max_key_mask+1)/2:
|
69 |
|
|
max_key = j
|
70 |
2 |
wzab |
fo.write(l+"\n")
|
71 |
|
|
# Now let's print necessary number of end records
|
72 |
|
|
for i in range(0,nrec):
|
73 |
7 |
wzab |
l = "1 " + key_format.format(max_key) + " " + pay_format.format(0)
|
74 |
2 |
wzab |
fo.write(l+"\n")
|
75 |
|
|
fo.close()
|