mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
Addressed issue #167
This commit is contained in:
parent
aca93321c7
commit
18d0fe0989
@ -1,6 +1,6 @@
|
|||||||
// File: Array8Sorter.v
|
// File: Array8Sorter.v
|
||||||
// Generated by MyHDL 1.0dev
|
// Generated by MyHDL 1.0dev
|
||||||
// Date: Sat Mar 19 17:27:30 2016
|
// Date: Sun May 15 11:40:06 2016
|
||||||
|
|
||||||
|
|
||||||
`timescale 1ns/10ps
|
`timescale 1ns/10ps
|
||||||
|
@ -26,6 +26,7 @@ import inspect
|
|||||||
import functools
|
import functools
|
||||||
|
|
||||||
import myhdl
|
import myhdl
|
||||||
|
from myhdl._compat import PY2
|
||||||
from myhdl import BlockError, BlockInstanceError, Cosimulation
|
from myhdl import BlockError, BlockInstanceError, Cosimulation
|
||||||
from myhdl._instance import _Instantiator
|
from myhdl._instance import _Instantiator
|
||||||
from myhdl._util import _flatten
|
from myhdl._util import _flatten
|
||||||
@ -66,8 +67,15 @@ def _getCallInfo():
|
|||||||
# caller may be undefined if instantiation from a Python module
|
# caller may be undefined if instantiation from a Python module
|
||||||
callerrec = None
|
callerrec = None
|
||||||
funcrec = stack[3]
|
funcrec = stack[3]
|
||||||
|
name = funcrec[3]
|
||||||
if len(stack) > 4:
|
if len(stack) > 4:
|
||||||
callerrec = stack[4]
|
callerrec = stack[4]
|
||||||
|
# special case for list comprehension's extra scope in PY3
|
||||||
|
if name == '<listcomp>':
|
||||||
|
if not PY2:
|
||||||
|
funcrec = stack[4]
|
||||||
|
if len(stack) > 5:
|
||||||
|
callerrec = stack[5]
|
||||||
|
|
||||||
name = funcrec[3]
|
name = funcrec[3]
|
||||||
frame = funcrec[0]
|
frame = funcrec[0]
|
||||||
|
160
myhdl/test/bugs/test_issue_167.py
Normal file
160
myhdl/test/bugs/test_issue_167.py
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
''' Bitonic sort '''
|
||||||
|
|
||||||
|
# http://www.myhdl.org/examples/bitonic/
|
||||||
|
|
||||||
|
from __future__ import absolute_import
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from random import randrange
|
||||||
|
|
||||||
|
from myhdl import Signal, intbv, \
|
||||||
|
always_comb, instance, \
|
||||||
|
delay, block, StopSimulation
|
||||||
|
|
||||||
|
|
||||||
|
ASCENDING = True
|
||||||
|
DESCENDING = False
|
||||||
|
|
||||||
|
|
||||||
|
# modules
|
||||||
|
|
||||||
|
@block
|
||||||
|
def compare(a_1, a_2, z_1, z_2, direction):
|
||||||
|
""" Combinatorial circuit with two input and two output signals.
|
||||||
|
Sorting to 'direction'. """
|
||||||
|
|
||||||
|
@always_comb
|
||||||
|
def logic():
|
||||||
|
''' Combinatorial logic '''
|
||||||
|
if direction == (a_1 > a_2):
|
||||||
|
z_1.next = a_2
|
||||||
|
z_2.next = a_1
|
||||||
|
else:
|
||||||
|
z_1.next = a_1
|
||||||
|
z_2.next = a_2
|
||||||
|
|
||||||
|
return logic
|
||||||
|
|
||||||
|
|
||||||
|
@block
|
||||||
|
def feedthru(in_a, out_z):
|
||||||
|
""" Equivalent of 'doing nothing'. """
|
||||||
|
|
||||||
|
@always_comb
|
||||||
|
def logic():
|
||||||
|
''' Combinatorial logic '''
|
||||||
|
out_z.next = in_a
|
||||||
|
|
||||||
|
return logic
|
||||||
|
|
||||||
|
|
||||||
|
@block
|
||||||
|
def bitonic_merge(list_a, list_z, direction):
|
||||||
|
""" bitonicMerge:
|
||||||
|
Generates the output from the input list of signals.
|
||||||
|
Recursive. """
|
||||||
|
len_list = len(list_a)
|
||||||
|
half_len = len_list//2
|
||||||
|
width = len(list_a[0])
|
||||||
|
|
||||||
|
if len_list > 1:
|
||||||
|
tmp = [Signal(intbv(0)[width:]) for _ in range(len_list)]
|
||||||
|
|
||||||
|
comp = [compare(list_a[i], list_a[i+half_len], tmp[i], tmp[i+half_len], \
|
||||||
|
direction) for i in range(half_len)]
|
||||||
|
|
||||||
|
lo_merge = bitonic_merge( tmp[:half_len], list_z[:half_len], direction )
|
||||||
|
hi_merge = bitonic_merge( tmp[half_len:], list_z[half_len:], direction )
|
||||||
|
|
||||||
|
return comp, lo_merge, hi_merge
|
||||||
|
else:
|
||||||
|
feed = feedthru(list_a[0], list_z[0])
|
||||||
|
return feed
|
||||||
|
|
||||||
|
|
||||||
|
@block
|
||||||
|
def bitonic_sort(list_a, list_z, direction):
|
||||||
|
""" bitonicSort:
|
||||||
|
Produces a bitonic sequence.
|
||||||
|
Recursive. """
|
||||||
|
len_list = len(list_a)
|
||||||
|
half_len = len_list//2
|
||||||
|
width = len(list_a[0])
|
||||||
|
|
||||||
|
if len_list > 1:
|
||||||
|
tmp = [Signal(intbv(0)[width:]) for _ in range(len_list)]
|
||||||
|
|
||||||
|
lo_sort = bitonic_sort( list_a[:half_len], tmp[:half_len], ASCENDING )
|
||||||
|
hi_sort = bitonic_sort( list_a[half_len:], tmp[half_len:], DESCENDING )
|
||||||
|
|
||||||
|
merge = bitonic_merge( tmp, list_z, direction )
|
||||||
|
return lo_sort, hi_sort, merge
|
||||||
|
else:
|
||||||
|
feed = feedthru(list_a[0], list_z[0])
|
||||||
|
return feed
|
||||||
|
|
||||||
|
|
||||||
|
# tests
|
||||||
|
|
||||||
|
@block
|
||||||
|
def array8sorter(a_0, a_1, a_2, a_3, a_4, a_5, a_6, a_7,
|
||||||
|
z_0, z_1, z_2, z_3, z_4, z_5, z_6, z_7):
|
||||||
|
''' Sort Array with 8 values '''
|
||||||
|
|
||||||
|
list_a = [a_0, a_1, a_2, a_3, a_4, a_5, a_6, a_7]
|
||||||
|
list_z = [z_0, z_1, z_2, z_3, z_4, z_5, z_6, z_7]
|
||||||
|
|
||||||
|
sort = bitonic_sort(list_a, list_z, ASCENDING)
|
||||||
|
return sort
|
||||||
|
|
||||||
|
|
||||||
|
class TestBitonicSort(unittest.TestCase):
|
||||||
|
''' Test class for bitonic sort '''
|
||||||
|
|
||||||
|
def test_sort(self):
|
||||||
|
""" Check the functionality of the bitonic sort """
|
||||||
|
length = 8
|
||||||
|
width = 4
|
||||||
|
|
||||||
|
@block
|
||||||
|
def test_impl():
|
||||||
|
''' test implementation '''
|
||||||
|
inputs = [ Signal(intbv(0)[width:]) for _ in range(length) ]
|
||||||
|
outputs = [ Signal(intbv(0)[width:]) for _ in range(length) ]
|
||||||
|
z_0, z_1, z_2, z_3, z_4, z_5, z_6, z_7 = outputs
|
||||||
|
a_0, a_1, a_2, a_3, a_4, a_5, a_6, a_7 = inputs
|
||||||
|
|
||||||
|
inst = array8sorter(a_0, a_1, a_2, a_3, a_4, a_5, a_6, a_7,
|
||||||
|
z_0, z_1, z_2, z_3, z_4, z_5, z_6, z_7)
|
||||||
|
|
||||||
|
@instance
|
||||||
|
def check():
|
||||||
|
''' testbench input and validation '''
|
||||||
|
for i in range(100):
|
||||||
|
data = [randrange(2**width) for i in range(length)]
|
||||||
|
for i in range(length):
|
||||||
|
inputs[i].next = data[i]
|
||||||
|
yield delay(10)
|
||||||
|
data.sort()
|
||||||
|
self.assertEqual(data, outputs, 'wrong data')
|
||||||
|
raise StopSimulation
|
||||||
|
|
||||||
|
return inst, check
|
||||||
|
|
||||||
|
inst = test_impl()
|
||||||
|
inst.run_sim()
|
||||||
|
|
||||||
|
|
||||||
|
# convert
|
||||||
|
|
||||||
|
def test_issue_167():
|
||||||
|
''' Convert to VHDL '''
|
||||||
|
length = 8
|
||||||
|
width = 4
|
||||||
|
sigs = [Signal(intbv(0)[width:]) for _ in range(2*length)]
|
||||||
|
|
||||||
|
inst = array8sorter( *sigs )
|
||||||
|
inst.convert( hdl='VHDL' )
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_issue_167()
|
Loading…
x
Reference in New Issue
Block a user