X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=regfile.py;fp=regfile.py;h=b54437228ecbb29b9d765f7d85beaa20ec6b2782;hb=6662edc348905f57db369f5cb18654e099008d9c;hp=0000000000000000000000000000000000000000;hpb=f21222df4fd037f0cc6ef11096d4eebb9ee0633d;p=rv32.git diff --git a/regfile.py b/regfile.py new file mode 100644 index 0000000..b544372 --- /dev/null +++ b/regfile.py @@ -0,0 +1,95 @@ +""" +/* + * Copyright 2018 Jacob Lifshay + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +`timescale 1ns / 1ps +`include "riscv.vh" +`include "cpu.vh" +""" + +from migen import * +from migen.fhdl import verilog + +class RegFile(Module): + + def __init__(self): + Module.__init__(self) + l = [] + for i in range(31): + r = Signal(32, name="register%d" % i) + l.append(r) + self.sync += r.eq(Constant(0, 32)) + self.registers = Array(l) + + self.ra_en = Signal() # read porta enable + self.rb_en = Signal() # read portb enable + self.w_en = Signal() # write enable + self.read_a = Signal(32) # result porta read + self.read_b = Signal(32) # result portb read + self.writeval = Signal(32) # value to write + self.rs_a = Signal(5) # register port a to read + self.rs_b = Signal(5) # register port b to read + self.rd = Signal(5) # register to write + + self.sync += If(self.ra_en, + self.read(self.rs_a, self.read_a) + ) + self.sync += If(self.rb_en, + self.read(self.rs_b, self.read_b) + ) + self.sync += If(self.w_en, + self.write_register(self.rd, self.writeval) + ) + + def read(self, regnum, dest): + """ sets the destination register argument + regnum = 0, dest = 0 + regnum != 0, dest = regs[regnum-1] + """ + return If(regnum == Constant(0, 5), + dest.eq(Constant(0, 32)) + ).Else( + dest.eq(self.registers[regnum-1]) + ) + + def write_register(self, regnum, value): + """ writes to the register file if the regnum is not zero + """ + return If(regnum != 0, + self.registers[regnum].eq(value) + ) + +if __name__ == "__main__": + example = RegFile() + print(verilog.convert(example, + { + example.ra_en, + example.rb_en, + example.w_en, + example.read_a, + example.read_b, + example.writeval, + example.rs_a, + example.rs_b, + example.rd, + })) +