/****************************************** Simple 16bit Non-Pipeline Processor (SN/X) V1.4.2 Synthesizable SFL source code. (C)Copyright by Naohiko Shimizu, 1998-2008. All rights are reserved. Update informations: 11-Jun-2008: minor change, use pc as an argument of ifetch stage. 05-Jun-2008: Simplify executes. 08-May-2008: Modified for Demonstration 06-Jul-2004: Modified for PATHENON synthesis 15-Feb-2003: Modified for Text book ******************************************/ %d ADD 0x0 %d AND 0x1 %d SLT 0x3 %d NOT 0x4 %d SR 0x6 %d HLT 0x7 %d LD 0x8 %d ST 0x9 %d LDA 0xa %d BZ 0xe %d BAL 0xf %d ITYPE opreg<15> %d OPCODE opreg<15:12> %d dR1 opreg<7:6> %d dR2 opreg<11:10> %d dR3 opreg<9:8> %d dI 16#opreg<7:0> declare snx { input inst<16> ; input datai<16> ; output datao<16> ; output iadrs<16> ; output adrs<16> ; instrout inst_read; instrout inst_write; instrout memory_read; instrout memory_write; instrout wb; instrout hlt; } declare inc16 { input in<16> ; output out<16> ; instrin do ; instr_arg do(in) ; } declare cla16 { input cin, in1<16>, in2<16> ; output out<16> ; instrin do ; instr_arg do(cin,in1,in2) ; } declare reg4 { input in<16>, inadr<2>, outaadr<2>, outbadr<2> ; output outa<16>, outb<16> ; instrin reada, readb, write; instr_arg reada(outaadr); instr_arg readb(outbadr); instr_arg write(inadr,in); } declare alu16 { input a<16>,b<16>; output out<16>; instrin do_add,do_slt,do_and,do_not,do_sr; instr_arg do_add(a,b); instr_arg do_slt(a,b); instr_arg do_and(a,b); instr_arg do_not(a); instr_arg do_sr(a); } module snx { input inst<16> ; input datai<16> ; output datao<16> ; output iadrs<16> ; output adrs<16> ; instrout inst_read; instrout inst_write; instrout memory_read; instrout memory_write; instrout wb; instrout hlt; reg_wr pc<16> ; reg_wr st0 ; reg st1, st2; inc16 inc ; reg4 gr; alu16 alu; reg opreg<16>, mar<16>, regnum<2>; sel opr1<16>, opr2<16>, nxpc<16>, br_taken; instrself dADD, dAND, dSLT, dNOT, dSR, dHLT, dLD, dST, dLDA, dBZ, dBAL; instrself decode, opr1zero, start; instr_arg memory_write(adrs,datao); instr_arg memory_read(adrs); instr_arg inst_read(iadrs); stage_name ifetch { task ift(pc) ; task iftm() ; } stage_name exec { task exe(opreg) ; } stage_name memex { task tstore(regnum, mar, pc); task tload(regnum, mar, pc); } par{ st0 := 0b1; st1 := st0; st2 := st1; if((st2 == 0b0) & (st1 == 0b1)) start(); } instruct start generate ifetch.ift(0x0000); instruct decode any { (OPCODE == ADD): dADD(); (OPCODE == AND): dAND(); (OPCODE == SLT): dSLT(); (OPCODE == NOT): dNOT(); (OPCODE == SR ): dSR(); (OPCODE == HLT): dHLT(); (OPCODE == LD ): dLD(); (OPCODE == ST ): dST(); (OPCODE == LDA): dLDA(); (OPCODE == BZ ): dBZ(); (OPCODE == BAL): dBAL(); } stage ifetch { relay exec.exe(inst_read(pc).inst); } stage exec { par { decode(); br_taken = dBAL | (dBZ & opr1zero); nxpc = inc.do(pc).out; opr1 = gr.reada(dR2).outa; if(opr1 == 0x0000) opr1zero(); any { ITYPE & (dR3 == 0b00): opr2 = 0x0000; else : opr2 = gr.readb(dR3).outb; } any { ITYPE: alu.do_add(dI,opr2); dADD : gr.write(dR1, alu.do_add(opr1,opr2).out); dSLT : gr.write(dR1, alu.do_slt(opr1,opr2).out); dAND : gr.write(dR1, alu.do_and(opr1,opr2).out); dNOT : gr.write(dR1, alu.do_not(opr1).out); dSR : gr.write(dR1, alu.do_sr(opr1).out); dLDA : gr.write(dR2, alu.out); dBAL : gr.write(dR2, nxpc); } any { dLD: relay memex.tload(dR2, alu.out, nxpc); dST: relay memex.tstore(dR2, alu.out, nxpc) ; br_taken:par { wb(); relay ifetch.ift(alu.out); } dHLT: par { hlt(); finish; } else: par { wb(); relay ifetch.ift(nxpc); } } } } stage memex { par { any { memex.tstore: memory_write(mar,gr.reada(regnum).outa); memex.tload: gr.write(regnum, memory_read(mar).datai); } relay ifetch.iftm(); wb(); } } } module reg4 { input in<16> ; input inadr<2> ; input outaadr<2> ; input outbadr<2> ; output outa<16> ; output outb<16> ; instrin reada; instrin readb; instrin write; reg r0<16>,r1<16>,r2<16>,r3<16> ; instruct reada any { outaadr == 0b00: outa = r0; outaadr == 0b01: outa = r1; outaadr == 0b10: outa = r2; outaadr == 0b11: outa = r3; } instruct readb any { outbadr == 0b00: outb = r0; outbadr == 0b01: outb = r1; outbadr == 0b10: outb = r2; outbadr == 0b11: outb = r3; } instruct write any { inadr == 0b00: r0 := in; inadr == 0b01: r1 := in; inadr == 0b10: r2 := in; inadr == 0b11: r3 := in; } } circuit inc16 { input in<16> ; output out<16> ; instrin do ; instruct do out = in + 0x0001; } circuit cla16 { input cin ; input in1<16> ; input in2<16> ; output out<16> ; instrin do ; instruct do out = in1 + in2 + (15#0b0 || cin); } module alu16 { input a<16>,b<16>; output out<16>; instrin do_add,do_slt,do_and,do_not,do_sr; cla16 cla; instruct do_add out = cla.do(0b0, a, b).out; instruct do_slt par { cla.do(0b1, a, ^b); out = 15#0b0 || ((a<15> & ^b<15>)| (cla.out<15> & ^a<15> & ^b<15>)| (cla.out<15> & a<15> & b<15>)); } instruct do_and out = a & b; instruct do_not out = ^a; instruct do_sr out = 0b0 || a<15:1> ; }