| import sys | |
| import random | |
| import re | |
| def top_harness(DIN_N, DOUT_N, f=sys.stdout): | |
| f.write( | |
| ''' | |
| module top(input clk, stb, di, output do); | |
| localparam integer DIN_N = %d; | |
| localparam integer DOUT_N = %d; | |
| reg [DIN_N-1:0] din; | |
| wire [DOUT_N-1:0] dout; | |
| reg [DIN_N-1:0] din_shr; | |
| reg [DOUT_N-1:0] dout_shr; | |
| always @(posedge clk) begin | |
| din_shr <= {din_shr, di}; | |
| dout_shr <= {dout_shr, din_shr[DIN_N-1]}; | |
| if (stb) begin | |
| din <= din_shr; | |
| dout_shr <= dout; | |
| end | |
| end | |
| assign do = dout_shr[DOUT_N-1]; | |
| roi roi ( | |
| .clk(clk), | |
| .din(din), | |
| .dout(dout) | |
| ); | |
| endmodule | |
| ''' % (DIN_N, DOUT_N)) | |
| def instance(mod, name, ports, params={}, sort=True, string_buffer=sys.stdout): | |
| # TODO: make this print nicer | |
| tosort = sorted if sort else lambda x: x | |
| print(' %s' % mod, file=string_buffer) | |
| if len(params): | |
| print(' #(', file=string_buffer) | |
| for i, (paramk, paramv) in enumerate(tosort(params.items())): | |
| comma = '' if i == len(params) - 1 else ',' | |
| print( | |
| ' .%s(%s)%s' % (paramk, paramv, comma), | |
| file=string_buffer) | |
| print(' )', file=string_buffer) | |
| print(' %s (' % name, file=string_buffer) | |
| for i, (portk, portv) in enumerate(tosort(ports.items())): | |
| comma = '' if i == len(ports) - 1 else ',' | |
| print( | |
| ' .%s(%s)%s' % (portk, portv, comma), | |
| file=string_buffer) | |
| print(' );', file=string_buffer) | |
| def quote(s): | |
| return '"' + s + '"' | |
| def unquote(s): | |
| assert s[0] == '"' and s[-1] == '"' | |
| return s[1:-1] | |
| def to_int(s): | |
| value = 0 | |
| match = re.search(r'^(\d+)\'([sS]*)([bBoOdDhH])(.*)', str(s)) | |
| if match: | |
| width = int(match.group(1)) | |
| signed = match.group(2) | |
| radix = match.group(3) | |
| value = match.group(4) | |
| # Convert to int type | |
| if re.match(r'[bB]', radix): | |
| value = int(value, 2) | |
| elif re.match(r'[oO]', radix): | |
| value = int(value, 8) | |
| elif re.match(r'[dD]', radix): | |
| value = int(value, 10) | |
| elif re.match(r'[hH]', radix): | |
| value = int(value, 16) | |
| else: | |
| raise ValueError('Don\'t know how to interpret input %s' % (s)) | |
| # Truncate to `width` bits | |
| value &= 2**width - 1 | |
| else: | |
| value = int(s) | |
| return value | |
| def parsei(s): | |
| if s == "1'b0": | |
| return 0 | |
| elif s == "1'b1": | |
| return 1 | |
| else: | |
| assert 0, 'FIXME' | |
| def parse_bitstr(s): | |
| n, postfix = s.split("'") | |
| n = int(n) | |
| assert postfix[0] == 'b' | |
| bitstr = postfix[1:] | |
| assert len(bitstr) == n | |
| return [int(x) for x in bitstr] | |
| def vrandbit(): | |
| if random.randint(0, 1): | |
| return "1'b1" | |
| else: | |
| return "1'b0" | |
| def vrandbits(n): | |
| ret = "%u'b" % n | |
| for _i in range(n): | |
| ret += str(random.randint(0, 1)) | |
| return ret |