/*------------------------------ Microprocessor STAR 16 Simple, Tiny but Advanced RISC ------------------------------*/ %i /* OP-Code */ %d SYS 0b000 %d LD 0b001 %d LH 0b010 %d STA 0b011 %d ALU 0b100 %d SFT 0b101 %d BRA 0b110 %d IO 0b111 /* Addressing Mode */ %d REG_A 0b00 %d IDX_A 0b01 %d IMD_A 0b10 %d ABS_A 0b11 /* SYSTEM function */ %d HLT 0b00 %d NOP 0b01 %d SCF 0b10 %d RCF 0b11 /* ALU Inst. Function */ %d ADD 0b000 %d ADC 0b001 %d SUB 0b010 %d SBC 0b011 %d CMP 0b100 %d AND 0b101 %d OR 0b110 %d XOR 0b111 /* Shift & Rotate Inst. Function */ %d SRA 0b000 %d SLA 0b001 %d SRL 0b010 %d SLL 0b011 %d RRA 0b100 %d RLA 0b101 %d RRL 0b110 %d RLL 0b111 /* I/O Function */ %d IN 0b0 %d OUT 0b1 /* Branch & Call Condition */ %d A 0b0000 %d Z 0b0001 %d NZ 0b0010 %d C 0b0011 %d NC 0b0100 %d V 0b0101 %d NV 0b0110 %d N 0b0111 %d NN 0b1000 /* Branch Type */ %d JP 0b0 %d CL 0b1 circuit_class ram { input adr<16>; input din<16>; output dout<16>; mem cell[65536]<16>; instrin read; instrin write; instr_arg read(adr); instr_arg write(adr,din); instruct read dout = cell[adr]; instruct write cell[adr] := din; } module top { submod_class star { input m_in<16>, inp<16>, inp_ok<1>, out_ok<1>, halt<1>; output adr<16>, m_out<16>, out<16>; instrin start; instrout m_read; instrout m_write; instrout out_c; instrout inp_c; } output adr<16>, m_out<16>; instrin start; star star; ram ram; instruct start star.start(); instruct star.m_write ram.write(star.adr,star.m_out); instruct star.m_read star.m_in = ram.read(star.adr).dout ; } module star { submod_class reg_file { input read<1>, write<1>, c<16>, a_sel<3>, b_sel<3>, c_sel<3>; output a<16>, b<16>; instrin do; instr_arg do(read, write, c, a_sel, b_sel, c_sel); } submod_class alu { input a<16>, b<16>, c_in<1>, fnc<3>; output s<16>, c_out<1>, v_out<1>; instrin do; instr_arg do(a, b, c_in, fnc); } submod_class shifter { input a<16>, c_in<1>, fnc<3>; output s<16>, c_out<1>; instrin do; instr_arg do(a, c_in, fnc); } input m_in<16>, inp<16>, inp_ok<1>, out_ok<1>, halt<1>; output adr<16>, m_out<16>, out<16>, c<1>, z<1>, v<1>, n<1>; reg_wr pc<16>; reg ir<16>, ir2<16>, mar<16>, opt<16>, cf<1>, zf<1>, vf<1>, nf<1>; sel_v s1<16>, s2<16>, s3<16>; tmp cd<1>; inc16 inc; alu alu; shifter shifter; reg_file reg_file; instrin start; instrout m_read; instrout m_write; instrout out_c; instrout inp_c; instr_arg m_read(adr); instr_arg m_write(adr, m_out); instr_arg inp_c(); instr_arg out_c(out); stage_name mpu{ task run(); } instruct start generate mpu.run(); stage mpu { state_name fetch, exec1, exec2; first_state fetch; state fetch par { if (halt) finish; pc := inc.do(pc).out; ir := m_read(pc).m_in; goto exec1; } state exec1 any { halt : finish; ^ir<8> & ^(/&ir<15:14>) : par { /* if (REG_A || IMD_A) && ^BRA && ^IO */ pc := inc.do(pc).out; ir := m_read(pc).m_in; goto exec1; } ir<9:8> == IDX_A : par { s1 = 0b00000000000 || ir<4:0>; s2 = reg_file.do(0b1, 0b0, 0x0000, 0b000, ir<7:5>, 0b000).b; s3 = alu.do(s1, s2, 0b0, ADD).s; mar := s3; pc := inc.do(pc).out; ir2 := m_read(pc).m_in; goto exec2; } ir<9:8> == ABS_A : par { s3 = m_read(pc).m_in; mar := s3; pc := inc.do(pc).out; goto exec2; } ir<15:13> == SYS : par { any { ir<1:0> == HLT : finish; ir<1:0> == SCF : cf := 0b1; ir<1:0> == RCF : cf := 0b0; } } (ir<15:13> == LD) & (ir<9:8> == REG_A) : par { s1 = reg_file.do(0b1, 0b1, s3, ir<7:5>, 0b000, ir<12:10>).a; s3 = s1; } (ir<15:13> == LD) & (ir<9:8> == IMD_A) : par { s1 = 16 # ir<7:0>; s3 = s1; reg_file.do(0b0, 0b1, s3, 0b000, 0b000, ir<12:10>); } ir<15:13> == LH : par { s1 = ir<7:0> || s2<7:0>; s3 = s1; s2 = reg_file.do(0b1, 0b1, s3, 0b000, ir<12:10>, ir<12:10>).b; } ir<15:13> == ALU : par { alt { (ir<2:0> == CMP) & (ir<9:8> == REG_A) : par { s1 = reg_file.do(0b1, 0b0, 0x0000, ir<7:5>, ir<12:10>, 0b000).a; s2 = reg_file.b; } (ir<2:0> == CMP) & (ir<9:8> == IMD_A) : par { s1 = 0b00000000000 || ir<7:3>; s2 = reg_file.do(0b1, 0b0, 0x0000, 0b000, ir<12:10>, 0b000).b; } ir<9:8> == REG_A : par { s1 = reg_file.do(0b1, 0b1, s3, ir<7:5>, ir<12:10>, ir<12:10>).a; s2 = reg_file.b; } ir<9:8> == IMD_A : par { s1 = 0b00000000000 || ir<7:3>; s2 = reg_file.do(0b1, 0b1, s3, 0b000, ir<12:10>, ir<12:10>).b; } } s3 = alu.do(s2, s1, cf, ir<2:0>).s; cf := alu.c_out; vf := alu.v_out; zf := ^/|s3; nf := s3<15>; } ir<15:13> == SFT : par { s2 = reg_file.do(0b1, 0b1, s3, 0b000, ir<12:10>, ir<12:10>).b; s3 = shifter.do(s2, cf, ir<2:0>).s; cf := shifter.c_out; zf := ^/|s3; } (ir<15:13> == BRA) & (ir<9:8> == REG_A) : par { pc := reg_file.do(0b1, 0b0, 0x0000, 0b111, 0b000, 0b000).a; goto fetch; } (ir<15:13> == IO) & (ir<0> == IN) : par { inp_c(); if (inp_ok) par { s3 = inp; reg_file.do(0b0, 0b1, s3, 0b000, 0b000, ir<12:10>); pc := inc.do(pc).out; ir := m_read(pc).m_in; } goto exec1; } (ir<15:13> == IO) & (ir<0> == OUT) : par { s2 = reg_file.do(0b1, 0b0, 0x0000, 0b000, ir<12:10>, 0b000).b; opt := s2; goto exec2; } } state exec2 any { halt : finish; ir<9:8> == IDX_A : par { ir := ir2; goto exec1; } (ir<9:8> == ABS_A) & ^(ir<15:13> == BRA) : goto fetch; ir<15:13> == LD : par { s3 = m_read(mar).m_in; reg_file.do(0b0, 0b1, s3, 0b000, 0b000, ir<12:10>); } ir<15:13> == STA : par { s2 = reg_file.do(0b1, 0b0, 0x0000, 0b000, ir<12:10>, 0b000).b; m_write(mar, s2); } ir<15:13> == BRA : par { any { ir<3:0> == A : cd = 0b1; ir<3:0> == Z : cd = zf; ir<3:0> == NZ : cd = ^zf; ir<3:0> == C : cd = cf; ir<3:0> == NC : cd = ^cf; ir<3:0> == V : cd = vf; ir<3:0> == NV : cd = ^vf; ir<3:0> == N : cd = nf; ir<3:0> == NN : cd = ^nf; } any { cd : par { pc := inc.do(mar).out; ir := m_read(mar).m_in; if (ir<4>) reg_file.do(0b0, 0b1, pc, 0b000, 0b000, 0b111); } else : par { pc := inc.do(pc).out; ir := m_read(pc).m_in; } } goto exec1; } ir<15:13> == IO : par { c = cf; z = zf; v = vf; n = nf; out_c(opt); any { out_ok : par { pc := inc.do(pc).out; ir := m_read(pc).m_in; goto exec1; } else : goto exec2; } } } } } module reg_file { input read<1>, write<1>, c<16>, a_sel<3>, b_sel<3>, c_sel<3>; output a<16>, b<16>; reg_wr reg_0<16>, reg_1<16>, reg_2<16>, reg_3<16>, reg_4<16>, reg_5<16>, reg_6<16>, reg_7<16>; instrin do; instruct do any { read == 0b1 : par { any { a_sel == 0b000 : a = reg_0; a_sel == 0b001 : a = reg_1; a_sel == 0b010 : a = reg_2; a_sel == 0b011 : a = reg_3; a_sel == 0b100 : a = reg_4; a_sel == 0b101 : a = reg_5; a_sel == 0b110 : a = reg_6; a_sel == 0b111 : a = reg_7; } any { b_sel == 0b000 : b = reg_0; b_sel == 0b001 : b = reg_1; b_sel == 0b010 : b = reg_2; b_sel == 0b011 : b = reg_3; b_sel == 0b100 : b = reg_4; b_sel == 0b101 : b = reg_5; b_sel == 0b110 : b = reg_6; b_sel == 0b111 : b = reg_7; } } write == 0b1 : any { c_sel == 0b000 : reg_0 := c; c_sel == 0b001 : reg_1 := c; c_sel == 0b010 : reg_2 := c; c_sel == 0b011 : reg_3 := c; c_sel == 0b100 : reg_4 := c; c_sel == 0b101 : reg_5 := c; c_sel == 0b110 : reg_6 := c; c_sel == 0b111 : reg_7 := c; } } } module alu { submod_class add4 { input a<4>, b<4>, c_in; output s<4>, c_out; instrin do; instr_arg do(a, b, c_in); } input a<16>, b<16>, c_in<1>, fnc<3>; output s<16>, c_out<1>, v_out<1>; tmp b_tmp<16>; add4 add_0, add_1, add_2, add_3; instrin do; instruct do any { fnc == ADD : par { s = add_3.do(a<15:12>, b<15:12>, add_2.c_out).s || add_2.do( a<11:8>, b<11:8>, add_1.c_out).s || add_1.do( a<7:4>, b<7:4>, add_0.c_out).s || add_0.do( a<3:0>, b<3:0>, 0b0).s; c_out = add_3.c_out; v_out = (^a<15> & ^b<15> & s<15>) | (a<15> & b<15> & ^s<15>); } fnc == ADC : par { s = add_3.do(a<15:12>, b<15:12>, add_2.c_out).s || add_2.do( a<11:8>, b<11:8>, add_1.c_out).s || add_1.do( a<7:4>, b<7:4>, add_0.c_out).s || add_0.do( a<3:0>, b<3:0>, c_in).s; c_out = add_3.c_out; v_out = (^a<15> & ^b<15> & s<15>) | (a<15> & b<15> & ^s<15>); } (fnc == SUB) | (fnc == CMP) : par { b_tmp = ^b; s = add_3.do(a<15:12>, b_tmp<15:12>, add_2.c_out).s || add_2.do( a<11:8>, b_tmp<11:8>, add_1.c_out).s || add_1.do( a<7:4>, b_tmp<7:4>, add_0.c_out).s || add_0.do( a<3:0>, b_tmp<3:0>, 0b1).s; c_out = ^add_3.c_out; v_out = (^a<15> & b<15> & s<15>) | (a<15> & ^b<15> & ^s<15>); } fnc == SBC : par { b_tmp = ^b; s = add_3.do(a<15:12>, b_tmp<15:12>, add_2.c_out).s || add_2.do( a<11:8>, b_tmp<11:8>, add_1.c_out).s || add_1.do( a<7:4>, b_tmp<7:4>, add_0.c_out).s || add_0.do( a<3:0>, b_tmp<3:0>, ^c_in).s; c_out = ^add_3.c_out; v_out = (^a<15> & b<15> & s<15>) | (a<15> & ^b<15> & ^s<15>); } fnc == AND : par { s = a & b; c_out = 0b0; v_out = 0b0; } fnc == OR : par { s = a | b; c_out = 0b0; v_out = 0b0; } fnc == XOR : par { s = a @ b; c_out = 0b0; v_out = 0b0; } } } module add4 { input a<4>, b<4>, c_in; output s<4>, c_out; instrin do; tmp and_0, and_1, and_2, and_3; tmp or_0, or_1, or_2, or_3; tmp xor_0, xor_1, xor_2, xor_3; instruct do par { and_0 = a<0> & b<0>; and_1 = a<1> & b<1>; and_2 = a<2> & b<2>; and_3 = a<3> & b<3>; or_0 = a<0> | b<0>; or_1 = a<1> | b<1>; or_2 = a<2> | b<2>; or_3 = a<3> | b<3>; xor_0 = a<0> @ b<0>; xor_1 = a<1> @ b<1>; xor_2 = a<2> @ b<2>; xor_3 = a<3> @ b<3>; s = (((c_in & or_0 & or_1 & or_2) | (and_0 & or_1 & or_2) | (and_1 & or_2) | and_2) @ xor_3 ) || (((c_in & or_0 & or_1) | (and_0 & or_1) | and_1) @ xor_2) || (((c_in & or_0) | and_0) @ xor_1) || (c_in @ xor_0); c_out = (c_in & or_0 & or_1 & or_2 & or_3) | (and_0 & or_1 & or_2 & or_3) | (and_1 & or_2 & or_3) | (and_2 & or_3) | and_3; } } module shifter { input a<16>, c_in<1>, fnc<3>; output s<16>, c_out<1>; instrin do; instruct do any { fnc == SRA : par { s = a<15> || a<15:1>; c_out = a<0>; } (fnc == SLA) | (fnc == SLL) : par { s = a<14:0> || 0b0; c_out = a<15>; } fnc == SRL : par { s = 0b0 || a<15:1>; c_out = a<0>; } fnc == RRA : par { s = c_in || a<15:1>; c_out = a<0>; } fnc == RLA : par { s = a<14:0> || c_in; c_out = a<15>; } fnc == RRL : par { s = a<0> || a<15:1>; c_out = a<0>; } fnc == RLL : par { s = a<14:0> || a<15>; c_out = a<15>; } } }