Skip to content

Commit a54b0be

Browse files
committed
Working IPC b/w verilog test and python GUI
1 parent 6a45bed commit a54b0be

File tree

10 files changed

+213
-4
lines changed

10 files changed

+213
-4
lines changed

emulator/Makefile.mk

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ $(BUILD_EMULATOR)/%_test: $(SRC_EMULATOR)/%_test.v
88
iverilog -o $@ $^
99

1010
verilog_modules: $(patsubst $(SRC_EMULATOR)/%_test.v, $(BUILD_EMULATOR)/%_test, $(shell find $(SRC_EMULATOR) -name '*_test.v'))
11+
mkdir -p $(BUILD_EMULATOR)/io
1112

1213
test_verilog_modules: $(patsubst $(SRC_EMULATOR)/%_test.v, $(BUILD_EMULATOR)/%_test, $(shell find $(SRC_EMULATOR) -name '*_test.v'))
1314
$(foreach test_name, $^, echo "Executing $(test_name)" && ./$(test_name))
15+
16+
$(BUILD_EMULATOR)/module/libipc.so: $(SRC_EMULATOR)/module/ipc.cpp
17+
mkdir -p $(dir $@)
18+
g++ -shared -Wl,-soname,libipc.so -o $@ -fPIC $^
19+
20+
$(BUILD_EMULATOR)/module/ipc.py: $(SRC_EMULATOR)/module/ipc.py $(BUILD_EMULATOR)/module/libipc.so
21+
mkdir -p $(dir $@)
22+
cp -f $< $@
23+
24+
$(BUILD_EMULATOR)/module/ipc.o: $(SRC_EMULATOR)/module/ipc.cpp
25+
mkdir -p $(dir $@)
26+
g++ -o $@ $^

emulator/chipset_test.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ module chipset_test;
2323
$error("chipset failed");
2424
$fatal(1);
2525
end
26-
$finish();
26+
// $finish();
2727
end
2828
endmodule

emulator/module/ipc.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include <string>
2+
#include <iostream>
3+
#include <stdio.h>
4+
#include <sstream>
5+
6+
void handle_output(void (*callback)(int,int), int process_id, int value) {
7+
callback(process_id, value);
8+
}
9+
10+
void fast_io(void (*callback)(int,int)) {
11+
unsigned int pid, v;
12+
int len = scanf("IPC %x %x\n", &pid, &v);
13+
if(len>0) {
14+
handle_output(callback, pid, v);
15+
}
16+
}
17+
18+
extern "C" void fast_io_loop(void (*callback)(int,int)) {
19+
std::ios_base::sync_with_stdio(false);
20+
std::cin.tie(nullptr);
21+
while(1) {
22+
fast_io(callback);
23+
}
24+
}

emulator/module/ipc.v

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Handle Inter Process Communication
2+
// We were not able to figure out simpler way to do so.
3+
module IPCOut(
4+
input[15:0] process_id,
5+
input[31:0] value
6+
);
7+
8+
always @(value) begin
9+
$display("IPC %x %x", process_id, value);
10+
end
11+
endmodule

emulator/module/ipc_test.v

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
`include "emulator/module/ipc.v"
2+
3+
module ipc_test;
4+
reg[15:0] process_id;
5+
reg[31:0] value;
6+
7+
IPCOut dut(.process_id(process_id[15:0]), .value(value[31:0]));
8+
9+
initial begin
10+
# 5
11+
process_id = 10;
12+
# 1
13+
value = 20;
14+
# 1
15+
value = 25;
16+
# 1
17+
value = 30;
18+
end
19+
endmodule
20+

emulator/seq/io.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "stdio.h"
2+
#include "stdlib.h"
3+
4+
extern "C" void system_init() {
5+
printf("Start system initialization ...\n");
6+
}

emulator/seq/io_devices.v

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,58 @@
11
`include "emulator/com/rom.v"
2-
`define CONSDEV_ID 1
2+
`include "emulator/module/ipc.v"
3+
`define CONSDEV_ID 3
34
`define PROM_ID 2
45

6+
`define IO_DIR "build/emulator/io"
7+
8+
// Import the function called "system_init" implemented in C code
9+
510
module IODevices(
611
output[31:0] value_out,
712
input[7:0] device_id,
813
input[31:0] value_in,
914
input is_write,
1015
input clk);
1116

17+
integer fio;
18+
1219
reg[31:0] _data [255:0];
20+
initial begin
21+
// $fseek(fio, 0, 0);
22+
// system_init();
23+
end
24+
reg[15:0] process_id;
25+
// assign
26+
reg[31:0] value;
27+
IPCOut ipcout(.process_id(process_id[15:0]), .value(value[31:0]));
28+
1329
always @(negedge clk) begin
1430
// Write are triggered at negedge
1531
if (is_write) begin
1632
_data[device_id] <= value_in;
33+
process_id <= {8'b00000000, device_id};
34+
value <= value_in;
35+
36+
37+
// fio = $fopen("build/emulator/io/output.txt","w");
38+
// $fseek(fio, 0, 0);
39+
// $fwrite(fio, "%b\n", value_in);
40+
// $fflush(fio);
41+
// $fclose(fio);
1742
$display("IO:output[%x] <= %x", device_id, value_in);
1843
end
1944
end
2045

46+
reg[31:0] _ipc_input[0:15];
47+
// integer i;
48+
always @(posedge clk) begin
49+
// At some random interval
50+
$readmemb("/tmp/ourpc_input.txt", _ipc_input);
51+
// for (i=0; i<16; i=i+1) begin
52+
// $display("INPUT[%d]: %x", i, _ipc_input[i]);
53+
// end
54+
end
55+
2156
// PROM
2257
wire[31:0] prom_value;
2358
ROM_PINGPONG prom(.out(prom_value), .address(_data[`PROM_ID][15:0]));
@@ -26,7 +61,11 @@ module IODevices(
2661
always @(device_id) begin
2762
case (device_id)
2863
`PROM_ID: _value <= prom_value;
29-
`CONSDEV_ID: _value <= _data[`CONSDEV_ID];
64+
default:
65+
begin
66+
_value <= _ipc_input[device_id];
67+
// $display("IO:input[%x] <= %x", device_id, _value);
68+
end
3069
endcase
3170
end
3271
assign value_out = _value;

planner/__main__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from planner.asm import program_parser
66
from planner.sim import bin_parser
77
from planner.sim import devices
8-
from planner.sim.programs import ping_pong
8+
from planner.sim.programs import ping_pong, verilog_input
99

1010

1111
def args_parser():
@@ -26,6 +26,8 @@ def args_parser():
2626

2727
bin_parser = subparsers.add_parser("compile_and_execute")
2828
bin_parser.add_argument("program")
29+
30+
subparsers.add_parser("verilog_io")
2931
return parser
3032

3133
def main():
@@ -45,6 +47,8 @@ def main():
4547
_bin.set_output_device(6, devices.IntegerOutput("Screen6", bits=16))
4648
while True:
4749
_bin.step()
50+
if args.source == "verilog_io":
51+
verilog_input.start()
4852
if args.source == "compile_and_execute":
4953
if args.program == "ping_pong":
5054
ping_pong.start()

planner/sim/programs/verilog_input.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from planner.sim import verilog_devices, gui_devices
2+
from planner.sim import devices, gui_devices
3+
import pygame
4+
5+
def start():
6+
io = verilog_devices.VerilogIO()
7+
gui_manager = gui_devices.GUIDeviceManager()
8+
9+
input = devices.LatchInput("input", bits=4)
10+
gui_manager.add_device((0, 0), gui_devices.KeyPressedInput(input, {
11+
pygame.K_w: 0,
12+
pygame.K_s: 1,
13+
pygame.K_UP: 2,
14+
pygame.K_DOWN: 3,
15+
}))
16+
io.set_input_device(1, input)
17+
18+
display = devices.LEDDisplay("LED", use_print=False, width_anode=16, height_cathode=8)
19+
gui_manager.add_device((0, 0), gui_devices.GUILed(display))
20+
io.set_output_device(6, display.get_anodes()[0])
21+
io.set_output_device(7, display.get_cathodes()[0])
22+
io.run(blocking=False)
23+
gui_manager.draw_loop()

planner/sim/verilog_devices.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
from planner.sim import devices
2+
import threading
3+
import os
4+
from ctypes import cdll, c_int, CFUNCTYPE
5+
6+
IO_DEVICES = 16
7+
LIB = "build/emulator/module/libipc.so"
8+
INPUT_FILE = "/tmp/ourpc_input.txt"
9+
10+
global_io = None
11+
@CFUNCTYPE(None, c_int, c_int)
12+
def handle_output(pid, value):
13+
print("Got PID(%d) Value(%d)" % (pid, value))
14+
global_io.output_devices[pid].update(value)
15+
16+
def io_loop(hh):
17+
while True:
18+
s = input()
19+
print(s)
20+
s=s.split()
21+
if s[0]=="IPC":
22+
pid,value = s[1],s[2]
23+
pid=int(pid, 16)
24+
value=int(value, 16)
25+
print("Got PID(%d) Value(%d)" % (pid, value))
26+
dev = global_io.output_devices[pid]
27+
if dev is None:
28+
print("Device is None")
29+
else:
30+
dev.update(value)
31+
32+
class VerilogIO:
33+
def __init__(self):
34+
self.input_devices = [None]*IO_DEVICES
35+
self.output_devices = [None]*IO_DEVICES
36+
37+
# lib = cdll.LoadLibrary(LIB)
38+
# lib.fast_io_loop
39+
global global_io
40+
global_io = self
41+
self.mu = threading.Lock()
42+
self.t = threading.Thread(target=io_loop, args=[handle_output])
43+
44+
45+
def run(self, blocking=True):
46+
self.write_input(0, 0)
47+
self.t.start()
48+
if blocking:
49+
self.t.join()
50+
51+
def write_input(self, new_val, old_val):
52+
data = [0 if i is None else i.get() for i in self.input_devices]
53+
data_str = '\n'.join([
54+
"{:032b}".format(x) for x in data
55+
])
56+
with self.mu:
57+
with open(INPUT_FILE, "w") as f:
58+
f.write(data_str)
59+
60+
def set_input_device(self, index: int, d: devices.InputDevice):
61+
d.add_change_handler(self.write_input)
62+
self.input_devices[index] = d
63+
64+
def set_output_device(self, index: int, d: devices.Device):
65+
self.output_devices[index] = d
66+
67+
68+
69+

0 commit comments

Comments
 (0)