add names to read/write ports, add priority picker and other pieces
[soc.git] / src / experiment / cscore.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Array, Elaboratable
4
5 from regfile.regfile import RegFileArray
6 from scoreboard.fn_unit import IntFnUnit, FPFnUnit, LDFnUnit, STFnUnit
7 from scoreboard.fu_fu_matrix import FUFUDepMatrix
8 from scoreboard.global_pending import GlobalPending
9 from scoreboard.group_picker import GroupPicker
10 from scoreboard.issue_unit import IntFPIssueUnit
11
12
13 from alu_hier import Adder, Subtractor
14
15 class Scoreboard(Elaboratable):
16 def __init__(self, rwid, n_regs):
17 """ Inputs:
18
19 * :rwid: bit width of register file(s) - both FP and INT
20 * :n_regs: depth of register file(s) - number of FP and INT regs
21 """
22 self.rwid = rwid
23 self.n_regs = n_regs
24
25 # Register Files
26 self.intregs = RegFileArray(rwid, n_regs)
27 self.int_dest = self.intregs.write_port("dest")
28 self.int_src1 = self.intregs.read_port("src1")
29 self.int_src2 = self.intregs.read_port("src2")
30
31 self.fpregs = RegFileArray(rwid, n_regs)
32 self.fp_dest = self.fpregs.write_port("dest")
33 self.fp_src1 = self.fpregs.read_port("src1")
34 self.fp_src2 = self.fpregs.read_port("src2")
35
36 def elaborate(self, platform):
37 m = Module()
38 m.submodules.intregs = self.intregs
39 m.submodules.fpregs = self.fpregs
40
41 # Int ALUs
42 m.submodules.adder = adder = Adder(self.rwid)
43 m.submodules.subtractor = subtractor = Subtractor(self.rwid)
44 int_alus = [adder, subtractor]
45
46 # Int FUs
47 il = []
48 int_rd_pend_v = []
49 int_wr_pend_v = []
50 for i, a in enumerate(int_alus):
51 # set up Integer Function Unit, add to module (and python list)
52 fu = IntFnUnit(self.rwid, shadow_wid=0)
53 setattr(m.submodules, "intfu%d" % i, fu)
54 il.append(fu)
55 # collate the read/write pending vectors (to go into global pending)
56 int_rd_pend_v.append(fu.int_rd_pend_o)
57 int_wr_pend_v.append(fu.int_wr_pend_o)
58 int_fus = Array(il)
59
60 # Count of number of FUs
61 n_int_fus = len(il)
62 n_fp_fus = 0 # for now
63
64 n_fus = n_int_fus + n_fp_fus # plus FP FUs
65
66 # Integer FU Dep Matrix
67 m.submodules.intfudeps = intfudeps = FUFUDepMatrix(n_int_fus, n_int_fus)
68
69 # Integer Priority Picker 1: Adder + Subtractor
70 m.submodules.intpick1 = GroupPicker(2) # picks between add and sub
71
72 # Global Pending Vectors (INT and FP)
73 # NOTE: number of vectors is NOT same as number of FUs.
74 m.submodules.g_int_rd_pend_v = GlobalPending(self.rwid, int_rd_pend_v)
75 m.submodules.g_int_wr_pend_v = GlobalPending(self.rwid, int_wr_pend_v)
76
77 # Issue Unit
78 m.submodules.issueunit = IntFPIssueUnit(self.rwid,
79 n_int_fus,
80 n_fp_fus)
81 return m
82
83
84 def __iter__(self):
85 yield from self.intregs
86 yield from self.fpregs
87 #yield from self.int_src1
88 #yield from self.int_dest
89 #yield from self.int_src1
90 #yield from self.int_src2
91 #yield from self.fp_dest
92 #yield from self.fp_src1
93 #yield from self.fp_src2
94
95 def ports(self):
96 return list(self)
97
98
99 def scoreboard_sim(dut):
100 yield dut.dest_i.eq(1)
101 yield dut.issue_i.eq(1)
102 yield
103 yield dut.issue_i.eq(0)
104 yield
105 yield dut.src1_i.eq(1)
106 yield dut.issue_i.eq(1)
107 yield
108 yield
109 yield
110 yield dut.issue_i.eq(0)
111 yield
112 yield dut.go_read_i.eq(1)
113 yield
114 yield dut.go_read_i.eq(0)
115 yield
116 yield dut.go_write_i.eq(1)
117 yield
118 yield dut.go_write_i.eq(0)
119 yield
120
121 def test_scoreboard():
122 dut = Scoreboard(32, 8)
123 vl = rtlil.convert(dut, ports=dut.ports())
124 with open("test_scoreboard.il", "w") as f:
125 f.write(vl)
126
127 run_simulation(dut, scoreboard_sim(dut), vcd_name='test_scoreboard.vcd')
128
129 if __name__ == '__main__':
130 test_scoreboard()