/
pipelined.py
138 lines (90 loc) · 2.68 KB
/
pipelined.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
from myhdl import block, always_comb, instance, intbv, delay, always, instances
from myhdl import Signal as signal
from myhdl import ResetSignal as rsig
from myhdl import StopSimulation as expectation
from defs import *
from random import randrange
@block
def clock(clk):
@always(delay(10))
def clck():
clk.next = not clk
return clck
@block
def pc_adder(reset, clk, pc, pc_addr):
@always(clk.posedge)
def padder():
if reset.next == INACTIVE_HIGH:
pc_addr.next = (pc.next + 1)
return padder
@block
def pc_mux(reset, pc, pc_addr, jmp_addr, pc_sel):
@always_comb
def pmux():
if reset.next == INACTIVE_HIGH:
if pc_sel:
pc.next = jmp_addr
else:
pc.next = pc_addr
return pmux
@block
def pc_assign(reset, read_addr, pc):
@always_comb
def assign():
if reset.next == INACTIVE_HIGH:
read_addr.next = pc
return assign
@block
def inst_mem(reset, read_addr, instruction):
inx = open('mc_code').read().splitlines()
inst_ram = [signal(intbv(int(inx[i], 2))[CPU_BITS:]) for i in range(128)]
@always_comb
def itcm():
if reset.next == INACTIVE_HIGH:
instruction.next = inst_ram[read_addr]
return itcm
@block
def ifid(reset, instruction, ifid_reg, pc):
@always_comb
def reg():
if reset.next == INACTIVE_HIGH:
ifid_reg.next[CPU_BITS:0] = instruction
ifid_reg.next[IFID_REG_BITS:CPU_BITS] = pc
return reg
@block
def cpu_top(clk, reset):
pc, pc_addr, jmp_addr, read_addr, instruction = [signal(intbv(0)[CPU_BITS:]) for _ in range(5)]
pc_sel = signal(intbv(0)[1:])
ifid_reg = signal(intbv(0)[IFID_REG_BITS:])
padr = pc_adder(reset, clk, pc, pc_addr)
padr.convert(hdl='Verilog')
pcmx = pc_mux(reset, pc, pc_addr, jmp_addr, pc_sel)
pcmx.convert(hdl='Verilog')
pcmx = pc_mux(reset, pc, pc_addr, jmp_addr, pc_sel)
pcmx.convert(hdl='Verilog')
nxpc = pc_assign(reset, read_addr, pc)
nxpc.convert(hdl='Verilog')
imem = inst_mem(reset, read_addr, instruction)
imem.convert(hdl='Verilog')
rfdi = ifid(reset, instruction, ifid_reg, pc)
rfdi.convert(hdl='Verilog')
return instances()
@block
def top():
clk = signal(intbv(0)[1:])
reset = rsig(0, active=0, isasync=True)
cl = clock(clk)
cpu = cpu_top(clk, reset)
# cpu.convert(hdl='Verilog')
@instance
def stimulus():
reset.next = ACTIVE_LOW
yield clk.negedge
reset.next = INACTIVE_HIGH
return instances()
def main():
tb = top()
tb.config_sim(trace=True)
tb.run_sim(200)
if __name__ == '__main__':
main()