Repository navigation
Expand file tree
/
Copy pathopcode_executor.sv
More file actions
106 lines (81 loc) · 2.51 KB
/
Copy pathopcode_executor.sv
File metadata and controls
106 lines (81 loc) · 2.51 KB
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
`timescale 1 ps / 1 ps
interface opcode_executor_port ();
// whether the opcode executor has finished running opcodes
logic done;
// current and future states of the accumulator and preaccumulator
logic [15:0] acc, preAcc, nextAcc, nextPreAcc;
// whether the opcode executor should begin executing
logic proceed;
// whether the previous executor started a RAM load
logic waiting;
modport EXECUTOR(input acc, preAcc, proceed, waiting, output done, nextAcc, nextPreAcc);
modport HALF(output acc, preAcc, proceed, waiting, input done, nextAcc, nextPreAcc);
endinterface
module opcode_executor(
half_processor_in_port.HALF from_cpu,
opcode_executor_port.EXECUTOR half,
bit_stream_port.CLIENT rom,
cache_read_port.CLIENT ram
);
// is the executor waiting for RAM?
logic waiting, nextWaiting;
// is the executor done executing?
logic done;
import opcodes::*;
import stream_commands::*;
// are both memories ready?
logic ready;
assign ready = rom.ready & ram.ready;
// opcode input
logic [15:0] in;
// should the executor restart (beginning of CPU or instruction)
logic reset;
assign reset = from_cpu.reset | half.proceed;
// the number of completed opcodes
logic [2:0] completed;
// can the executor make progress?
logic active;
assign active = ready & ~done;
// does the basic_executor want to start waiting?
logic executorWaiting;
// is the basic_executor done?
logic executorDone;
basic_executor executor (
.from_cpu, .ram, .active, .completed,
.opcodes(rom.stream[0:5]),
.preIn(half.preAcc),
.in(waiting ? ram.data : half.acc),
.preOut(half.nextPreAcc),
.out(half.nextAcc),
.waiting(executorWaiting),
.done(executorDone)
);
assign rom.cmd = active ? STREAM_SHIFT : STREAM_NOOP;
assign rom.shift = {completed, 1'b0};
assign nextWaiting = active ? executorWaiting : waiting;
assign half.done = active ? executorDone : done;
always_ff @(posedge from_cpu.clk) begin
waiting <= reset ? half.waiting : nextWaiting;
done <= reset ? 1'b0 : half.done;
end
endmodule
module opcode_executor_tb();
logic clk, reset;
initial clk = 0;
initial forever #1 clk = ~clk;
// ram ramInstance();
// rom romInstance();
// rom_port romPort(clk);
// rom_port ramPort(clk);
// half_processor_in_port cpu();
// opcode_executor_port oep();
// bit_stream_port bsp();
// bit_stream bit_stream(reset, bit_stream_port.STREAM, romPort);
// opcode_executor dut(cpu, oep, bsp, ramPort);
initial begin
reset = 1;
@(posedge clk) reset = 0;
repeat (100) @(posedge clk);
$stop();
end
endmodule