From 6f35af64465700971bce1e4dae1f7e69c2ec25ad Mon Sep 17 00:00:00 2001 From: Tobias Platen Date: Sat, 25 Jan 2020 13:22:44 +0100 Subject: [PATCH] convert ram tp modules --- src/iommu/axi_rab/ram_tp_no_change.py | 108 ++++++++++-------- src/iommu/axi_rab/ram_tp_write_first.py | 104 +++++++++-------- .../axi_rab/test/test_ram_tp_no_change.py | 18 +++ 3 files changed, 139 insertions(+), 91 deletions(-) create mode 100644 src/iommu/axi_rab/test/test_ram_tp_no_change.py diff --git a/src/iommu/axi_rab/ram_tp_no_change.py b/src/iommu/axi_rab/ram_tp_no_change.py index 958ffde3..bdcd5550 100644 --- a/src/iommu/axi_rab/ram_tp_no_change.py +++ b/src/iommu/axi_rab/ram_tp_no_change.py @@ -1,25 +1,3 @@ -# this file has been generated by sv2nmigen - -from nmigen import Signal, Module, Const, Cat, Elaboratable - - -class ram_tp_no_change(Elaboratable): - - def __init__(self): - self.clk = Signal() # input - self.we = Signal() # input - self.addr0 = Signal() # input - self.addr1 = Signal() # input - self.d_i = Signal() # input - self.d0_o = Signal() # output - self.d1_o = Signal() # output - - def elaborate(self, platform=None): - m = Module() - m.d.comb += self.d0_o.eq(self.d0) - m.d.comb += self.d1_o.eq(self.d1) - return m - # // Copyright 2018 ETH Zurich and University of Bologna. # // Copyright and related rights are licensed under the Solderpad Hardware # // License, Version 0.51 (the "License"); you may not use this file except in @@ -42,11 +20,17 @@ class ram_tp_no_change(Elaboratable): # * # * For more information, see Xilinx PG058 Block Memory Generator Product Guide. # */ + +from nmigen import Signal, Module, Const, Cat, Elaboratable +from nmigen import Memory + +import math + # # module ram_tp_no_change # #( -# parameter ADDR_WIDTH = 10, -# parameter DATA_WIDTH = 36 +ADDR_WIDTH = 10 +DATA_WIDTH = 36 # ) # ( # input clk, @@ -57,25 +41,57 @@ class ram_tp_no_change(Elaboratable): # output [DATA_WIDTH-1:0] d0_o, # output [DATA_WIDTH-1:0] d1_o # ); -# -# localparam DEPTH = 2**ADDR_WIDTH; -# -# (* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram[DEPTH]; -# reg [DATA_WIDTH-1:0] d0; -# reg [DATA_WIDTH-1:0] d1; -# -# always_ff @(posedge clk) begin -# if(we == 1'b1) begin -# ram[addr0] <= d_i; -# end else begin -# d0 <= ram[addr0]; -# end -# d1 <= ram[addr1]; -# end -# -# assign d0_o = d0; -# assign d1_o = d1; -# -#endmodule // ram_tp_no_change -# -# + + +class ram_tp_no_change(Elaboratable): + + def __init__(self): + self.we = Signal() # input + self.addr0 = Signal(ADDR_WIDTH) # input + self.addr1 = Signal(ADDR_WIDTH) # input + self.d_i = Signal(DATA_WIDTH) # input + self.d0_o = Signal(DATA_WIDTH) # output + self.d1_o = Signal(DATA_WIDTH) # output + + DEPTH = int(math.pow(2, ADDR_WIDTH)) + self.ram = Memory(DATA_WIDTH, DEPTH) + # + # localparam DEPTH = 2**ADDR_WIDTH; + # + # (* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram[DEPTH]; + # reg [DATA_WIDTH-1:0] d0; + # reg [DATA_WIDTH-1:0] d1; + # + # always_ff @(posedge clk) begin + # if(we == 1'b1) begin + # ram[addr0] <= d_i; + # end else begin + # only change data if we==false + # d0 <= ram[addr0]; + # end + # d1 <= ram[addr1]; + # end + # + # assign d0_o = d0; + # assign d1_o = d1; + # + + def elaborate(self, platform=None): + m = Module() + m.submodules.read_ram0 = read_ram0 = self.ram.read_port() + m.submodules.read_ram1 = read_ram1 = self.ram.read_port() + m.submodules.write_ram = write_ram = self.ram.write_port() + + # write port + m.d.comb += write_ram.en.eq(self.we) + m.d.comb += write_ram.addr.eq(self.addr0) + m.d.comb += write_ram.data.eq(self.d_i) + + # read ports + m.d.comb += read_ram0.addr.eq(self.addr0) + m.d.comb += read_ram1.addr.eq(self.addr1) + with m.If(self.we == 0): + m.d.sync += self.d0_o.eq(read_ram0.data) + m.d.sync += self.d1_o.eq(read_ram1.data) + + return m diff --git a/src/iommu/axi_rab/ram_tp_write_first.py b/src/iommu/axi_rab/ram_tp_write_first.py index e1f5c029..7a21969c 100644 --- a/src/iommu/axi_rab/ram_tp_write_first.py +++ b/src/iommu/axi_rab/ram_tp_write_first.py @@ -1,25 +1,3 @@ -# this file has been generated by sv2nmigen - -from nmigen import Signal, Module, Const, Cat, Elaboratable - - -class ram_tp_write_first(Elaboratable): - - def __init__(self): - self.clk = Signal() # input - self.we = Signal() # input - self.addr0 = Signal() # input - self.addr1 = Signal() # input - self.d_i = Signal() # input - self.d0_o = Signal() # output - self.d1_o = Signal() # output - - def elaborate(self, platform=None): - m = Module() - m.d.comb += self.d0_o.eq(self.None) - m.d.comb += self.d1_o.eq(self.None) - return m - # // Copyright 2018 ETH Zurich and University of Bologna. # // Copyright and related rights are licensed under the Solderpad Hardware # // License, Version 0.51 (the "License"); you may not use this file except in @@ -41,11 +19,16 @@ class ram_tp_write_first(Elaboratable): # * # * For more information, see Xilinx PG058 Block Memory Generator Product Guide. # */ + +from nmigen import Signal, Module, Const, Cat, Elaboratable +from nmigen import Memory + +import math # # module ram_tp_write_first # #( -# parameter ADDR_WIDTH = 10, -# parameter DATA_WIDTH = 36 +ADDR_WIDTH = 10 +DATA_WIDTH = 36 # ) # ( # input clk, @@ -56,24 +39,55 @@ class ram_tp_write_first(Elaboratable): # output [DATA_WIDTH-1:0] d0_o, # output [DATA_WIDTH-1:0] d1_o # ); -# -# localparam DEPTH = 2**ADDR_WIDTH; -# -# (* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram[DEPTH]; -# reg [ADDR_WIDTH-1:0] raddr0; -# reg [ADDR_WIDTH-1:0] raddr1; -# -# always_ff @(posedge clk) begin -# if(we == 1'b1) begin -# ram[addr0] <= d_i; -# end -# raddr0 <= addr0; -# raddr1 <= addr1; -# end -# -# assign d0_o = ram[raddr0]; -# assign d1_o = ram[raddr1]; -# -#endmodule // ram -# -# + + +class ram_tp_write_first(Elaboratable): + + def __init__(self): + self.we = Signal() # input + self.addr0 = Signal(ADDR_WIDTH) # input + self.addr1 = Signal(ADDR_WIDTH) # input + self.d_i = Signal(DATA_WIDTH) # input + self.d0_o = Signal(DATA_WIDTH) # output + self.d1_o = Signal(DATA_WIDTH) # output + + DEPTH = int(math.pow(2, ADDR_WIDTH)) + self.ram = Memory(DATA_WIDTH, DEPTH) + + # + # localparam DEPTH = 2**ADDR_WIDTH; + # + # (* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram[DEPTH]; + # reg [ADDR_WIDTH-1:0] raddr0; + # reg [ADDR_WIDTH-1:0] raddr1; + # + # always_ff @(posedge clk) begin + # if(we == 1'b1) begin + # ram[addr0] <= d_i; + # end + # raddr0 <= addr0; + # raddr1 <= addr1; + # end + # + # assign d0_o = ram[raddr0]; + # assign d1_o = ram[raddr1]; + # + + def elaborate(self, platform=None): + m = Module() + m.submodules.read_ram0 = read_ram0 = self.ram.read_port() + m.submodules.read_ram1 = read_ram1 = self.ram.read_port() + m.submodules.write_ram = write_ram = self.ram.write_port() + + # write port + m.d.comb += write_ram.en.eq(self.we) + m.d.comb += write_ram.addr.eq(self.addr0) + m.d.comb += write_ram.data.eq(self.d_i) + + # read ports + m.d.comb += read_ram0.addr.eq(self.addr0) + m.d.comb += read_ram1.addr.eq(self.addr1) + m.d.sync += self.d0_o.eq(read_ram0.data) + m.d.sync += self.d1_o.eq(read_ram1.data) + + return m diff --git a/src/iommu/axi_rab/test/test_ram_tp_no_change.py b/src/iommu/axi_rab/test/test_ram_tp_no_change.py new file mode 100644 index 00000000..8d23ef05 --- /dev/null +++ b/src/iommu/axi_rab/test/test_ram_tp_no_change.py @@ -0,0 +1,18 @@ +from ram_tp_write_first import ram_tp_write_first +from nmigen.compat.sim import run_simulation +import sys +sys.path.append("../") + + +def tbench(dut): + yield dut.we.eq(1) + for i in range(0, 255): + yield dut.addr0.eq(i) + yield dut.d_i.eq(i) + yield + + +if __name__ == "__main__": + dut = ram_tp_write_first() + run_simulation(dut, tbench(dut), vcd_name="ram_tp_write_first.vcd") + print("ram_tp_write_first Unit Test Success") -- 2.30.2