OpenCores
URL https://opencores.org/ocsvn/myblaze/myblaze/trunk

Subversion Repositories myblaze

[/] [myblaze/] [trunk/] [rtl/] [bram.py] - Blame information for rev 6

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 rockee
# -*- coding: utf-8 -*-
2
"""
3
    bram.py
4
    =======
5
 
6
    Block RAM
7
 
8 5 rockee
    :copyright: Copyright (c) 2010 Jian Luo
9
    :author-email: jian.luo.cn(at_)gmail.com
10
    :license: LGPL, see LICENSE for details
11 2 rockee
    :revision: $Id: bram.py 6 2010-11-21 23:18:44Z rockee $
12
"""
13
 
14
from myhdl import *
15
from defines import *
16
from functions import *
17
from debug import *
18
 
19
def BRAMInitial(ram, filename, clock):
20
    __verilog__ = """
21
    initial $readmemh("%(filename)s", %(ram)s);
22
    """
23
    __vhdl__ = """
24
    """
25
    @instance
26
    def initial():
27
        vals = open(filename).readlines()
28
        for i,v in enumerate(vals):
29
            ram[i].next = int(v, 16)
30
        yield clock.negedge
31
    return instances()
32
 
33
# XXX: Hacked to make $readmemh work
34
class RAM(list):
35
    # representation 
36
    def __str__(self):
37
        from myhdl._extractHierarchy import _memInfoMap
38
        if id(self) in _memInfoMap:
39
            return _memInfoMap[id(self)].name
40
        else:
41
            return list.__str__(self)
42
 
43
def BRAM(
44
        data_out,
45
        data_in,
46
        address,
47
        write,
48
        enable,
49
        clock,
50
        width=8,
51
        size=16,
52
        filename='',
53
        ):
54
    """
55
    Single Port Synchronous RAM with Old Data Read-During-Write Behavior
56
    """
57
    max = 2**size
58
    ram = RAM(Signal(intbv(0)[width:]) for i in range(max))
59
    if filename:
60
        init = BRAMInitial(ram, filename, clock)
61
 
62
    @always(clock.posedge)
63
    def logic():
64
        if enable:
65
            if write:
66
                ram[int(address)].next = data_in
67
            data_out.next = ram[int(address)%max]
68
 
69
    return instances()
70
 
71
def BankedBRAM(
72
        data_out,
73
        data_in,
74
        address,
75
        write,
76
        enable,
77
        clock,
78
        width=32,
79
        bank_size=2,
80
        size=16,
81 5 rockee
        to_verilog=1,
82 2 rockee
        filename_pattern='',
83
        ):
84
    # XXX: Verilog just don't allow dynamic register slicing
85
    # have to fix ram shape to 4x8bit
86 6 rockee
    if to_verilog:
87 2 rockee
        width=32
88
        bank_size=2
89
    bank_count = 2 ** bank_size
90
    bank_width = width/bank_count
91
    bank_in = [Signal(intbv(0)[bank_width:]) for i in range(bank_count)]
92
    bank_out = [Signal(intbv(0)[bank_width:]) for i in range(bank_count)]
93
    bank_wre = [Signal(False) for i in range(bank_count)]
94
    bank_addr = Signal(intbv(0)[len(address)-bank_size:])
95
    if filename_pattern:
96
        bank = [BRAM(data_out=bank_out[i], data_in=bank_in[i],
97
                     address=bank_addr, write=bank_wre[i],
98
                     enable=enable, clock=clock,
99
                     width=bank_width, size=size-bank_size,
100
                     filename=filename_pattern%i)
101
 
102
                    for i in range(bank_count)]
103
    else:
104
        bank = [BRAM(data_out=bank_out[i], data_in=bank_in[i],
105
                     address=bank_addr, write=bank_wre[i],
106
                     enable=enable, clock=clock,
107
                     width=bank_width, size=size-bank_size,)
108
 
109
                    for i in range(bank_count)]
110
 
111 6 rockee
    if to_verilog:
112 2 rockee
        @always_comb
113 6 rockee
        def reassemble():
114 2 rockee
            bank_addr.next = address[:bank_size]
115
            for i in range(bank_count):
116
                bank_wre[i].next = write[i]
117
            bank_in[0].next = data_in[8:]
118
            bank_in[1].next = data_in[16:8]
119
            bank_in[2].next = data_in[24:16]
120
            bank_in[3].next = data_in[32:24]
121
            data_out.next = concat(bank_out[3], bank_out[2],
122
                                   bank_out[1], bank_out[0])
123
 
124 6 rockee
    else:
125
        @always_comb
126
        def reassemble():
127
            bank_addr.next = address[:bank_size]
128
            tmp = intbv(0)[width:]
129
            tmp_low = intbv(0)[width-bank_width:]
130
            for i in range(bank_count):
131
                bank_wre[i].next = write[i]
132
                bank_in[i].next = data_in[(i+1)*bank_width:i*bank_width]
133
                tmp_low[:] = tmp[:bank_width]
134
                tmp[:] = concat(bank_out[i], tmp_low)
135
            data_out.next = tmp
136 2 rockee
 
137 6 rockee
    return bank, reassemble
138 2 rockee
 
139
if __name__ == '__main__':
140
    data_out = Signal(intbv(0)[32:])
141
    data_in = Signal(intbv(0)[32:])
142
    address = Signal(intbv(0)[16:])
143
    write = Signal(intbv(0)[4:])
144
    bram_write = Signal(False)
145
    clock = Signal(False)
146
    enable = Signal(False)
147
    bram_kw = dict(
148
        func=BRAM,
149
        data_out=data_out,
150
        data_in=data_in,
151
        address=address,
152
        write=bram_write,
153
        enable=enable,
154
        clock=clock,
155
        width=32,
156
        size=8,
157
        filename='rom.vmem',
158
    )
159
    kw = dict(
160
        data_out=data_out,
161
        data_in=data_in,
162
        address=address,
163
        write=write,
164
        enable=enable,
165
        clock=clock,
166
        width=32,
167
        bank_size=2,
168
        size=8,
169 6 rockee
        filename_pattern='rom%d.vmem',
170 2 rockee
    )
171 6 rockee
    toVerilog(BankedBRAM, to_verilog=True, **kw)
172
    #toVerilog(**bram_kw)
173
    toVHDL(BankedBRAM, **kw)
174 2 rockee
 
175
### EOF ###
176
# vim:smarttab:sts=4:ts=4:sw=4:et:ai:tw=80:
177
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.