module system { submod_type kamuri { /* instruction/data memory I/O pins */ input ibus<32>, dbus_in<16>; output iaddr<14>, daddr<15>, dmask<2>, dbus_out<16>; output read_write; /* 0: read data 1: write data */ instrin chip_enable; /* chip activation */ instrin reset; /* reset */ instrin start_stop; /* start/stop toggle */ instrin irdy; /* instruction words has loaded on `ibus' */ instrin drdy; /* data words has loaded on `dbus' */ instrin dack; /* data store request has acknowledged */ instrout iread; /* instruction fetch request */ instrout daccess; /* data access request */ } submod_type imem { input addr<14>; output ibus<32>; instrin read; instrin wait; instrout rdy; } submod_type dmem { input read_write; /* 0: read 1: write */ input addr<15>, mask<2>; bidirect dbus<16>; instrin access; instrin wait; instrout rdy, ack; } submod_type tester { input read_write; input addr<15>, mask<2>; input tbus<16>; instrin access; instrin wait; instrin reset; instrout ack; } kamuri KAMURI; imem IMEM; dmem DMEM; tester TESTER; instrin chip_enable; /* chip activation */ instrin reset; /* reset */ instrin start_stop; /* start/stop toggle */ instrin iwait, dwait; /* for memory wait simulation */ instruct_arg KAMURI.chip_enable(); instruct_arg KAMURI.reset(); instruct_arg KAMURI.start_stop(); instruct_arg KAMURI.irdy(ibus); instruct_arg KAMURI.drdy(dbus_in); instruct_arg KAMURI.dack(); instruct_arg IMEM.read(addr); instruct_arg IMEM.wait(); instruct_arg DMEM.access(read_write, addr, mask); instruct_arg DMEM.wait(); instruct_arg TESTER.access(read_write, addr, mask); instruct_arg TESTER.wait(); instruct chip_enable KAMURI.chip_enable(); instruct reset par { KAMURI.reset(); TESTER.reset(); } instruct start_stop KAMURI.start_stop(); instruct iwait IMEM.wait(); instruct dwait par { DMEM.wait(); TESTER.wait(); } instruct KAMURI.iread IMEM.read(KAMURI.iaddr); instruct IMEM.rdy KAMURI.irdy(IMEM.ibus); instruct KAMURI.daccess par { any { KAMURI.read_write : par { DMEM.dbus = KAMURI.dbus_out; TESTER.tbus = KAMURI.dbus_out; } } any { ^KAMURI.daddr<14> : DMEM.access(KAMURI.read_write, KAMURI.daddr, KAMURI.dmask); else : TESTER.access(KAMURI.read_write, KAMURI.daddr, KAMURI.dmask); } } instruct DMEM.rdy KAMURI.drdy(DMEM.dbus); instruct DMEM.ack KAMURI.dack(); instruct TESTER.ack KAMURI.dack(); } module dmem { input read_write; /* 0: read 1: write */ input addr<15>, mask<2>; bidirect dbus<16>; mem cell[65536]<8>; instrin access; instrin wait; instrout rdy, ack; instruct_arg rdy(dbus); instruct_arg ack(); instruct access any { ^wait : any { (^read_write)/*read */: rdy(cell[addr||0b1]||cell[addr||0b0]); ( read_write)/*write*/: any { mask<0> : par { cell[addr||0b0] := dbus< 7:0>; ack(); } mask<1> : par { cell[addr||0b1] := dbus<15:8>; ack(); } } } wait : ; } } module tester { circuit_type cmp8 { input a<8>, b<8>; output eq; instrin do; instr_arg do(a, b); instruct do par { eq = ^(/|(a @ b)); } } circuit_type inc8 { input a<8>; output q<8>; instrin do; instruct_arg do(a); instruct do q = a + 0x01; } input read_write; /* 0: read 1: write */ input addr<15>, mask<2>; input tbus<16>; reg Fail<8>, True<8>; mem cell[65536]<8>; instrin access; instrin wait; instrin reset; instrout ack; cmp8 cmp8_a, cmp8_b; inc8 inc; instruct_arg ack(); instruct access any { ^wait : any { ( read_write)/*write*/: par { cmp8_a.do(cell[addr||0b0], tbus< 7:0>); cmp8_b.do(cell[addr||0b1], tbus<15:8>); ack(); any { (mask<0> & ^cmp8_a.eq) | (mask<1> & ^cmp8_b.eq) : Fail := inc.do(Fail).q; else : True := inc.do(True).q; } } } wait : ; } instruct reset par { True := 0b00000000; Fail := 0b00000000; } } module imem { input addr<14>; output ibus<32>; mem cell[32768]<16>; instrin read; instrin wait; instrout rdy; instruct_arg rdy(ibus); instruct read any { ^wait : rdy(cell[addr||0b1]||cell[addr||0b0]); wait : ; } }