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
|
||||
// Generated by MyHDL 1.0dev
|
||||
// Date: Sat Mar 19 17:27:30 2016
|
||||
// Date: Sun May 15 11:40:06 2016
|
||||
|
||||
|
||||
`timescale 1ns/10ps
|
||||
|
@ -26,6 +26,7 @@ import inspect
|
||||
import functools
|
||||
|
||||
import myhdl
|
||||
from myhdl._compat import PY2
|
||||
from myhdl import BlockError, BlockInstanceError, Cosimulation
|
||||
from myhdl._instance import _Instantiator
|
||||
from myhdl._util import _flatten
|
||||
@ -66,8 +67,15 @@ def _getCallInfo():
|
||||
# caller may be undefined if instantiation from a Python module
|
||||
callerrec = None
|
||||
funcrec = stack[3]
|
||||
name = funcrec[3]
|
||||
if len(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]
|
||||
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