/* yasep/VHDL/config.js This file is distributed under terms of the Affero GPL v3 license or later, see http://yasep.org 2009-05-28 : yasep/tools/generate_VHDL.html created by whygee at f-cpu.org from opcode_map.html 2009-06-06 2009-07-11 2009-07-28 : Y 20090830 : config panel 20090920 : SULV->SLV dim. févr. 12 06:49:50 CET 2012 : windowed version dim. févr. 19 09:32:45 CET 2012 : adding valid instructions and such (should be generalised with "profiles") lun. févr. 20 12:14:17 CET 2012 : profiles almost working jeu. mai 10 05:17:49 CEST 2012 : moved to VHDL lun. juil. 29 08:21:49 CEST 2013 : trying to rebuild, as cleanup looks too hard 20130809 added parking Purpose : Makes buttons that configure a profile and export the corresponding VHDL definitions Quite buggy, i'm rebuilding it... */ init_obj.push(config={ win: null, opcodes_id:[], mul_id:[], cond_id:[], size_id:[], park_id:[], empty:false, multable:{ "MUL8L":8, "MUL8H":8, "MULI":8, "LUT8":8, "MUL16H":16, "MUL16L":16}, changeInstruction: function(val,n,force) { // n:string (instruction name) if (typeof config.core!="object") wa("VHDL/config#name=empty"); // change only if different if ((force===true) || (val != config.opcodes_id[n].checked)) { var c=config.core, t; // Force some values if we're in "auto-collection" mode if((val===true) && config.empty) { if((c.datapath!=32) && config.Y32_id[n]){ config.core.datapath=32; config.win.shortmsg("force datapath=32"); } if ((t=config.multable[n]) && (t>c.multiplier)){ config.core.multiplier=t; config.win.shortmsg("force multiplier="+t); } } c.valid_instructions[n]=(val===true)? 1 : 0; config.opcodes_id[n].checked=val; delay(config.delay_check); } }, changeBox: function() { config.changeInstruction(this.checked, this.id, true); }, // check the configuration sanity // Warning !! potential crazy loop because changeInstruction // delay-calls check which calls changeInstruction... check: function() { var n, c=config.core; switch (c.multiplier) { case 0: case 8: // just filters the valid values. case 16: break; default : c.multiplier=0; } if (c.datapath!=32) c.datapath =16; config.size_id[c.datapath].checked=true; switch (c.datapath) { case 16: if (c.multiplier==16) c.multiplier =8; // constrain the MUL size // disable all the Y32only for (n in config.Y32_id) config.changeInstruction(false,n); // enable the Y16 break; case 32: // disable all the Y16only // enable the Y32 break; } if (c.Park!=1) c.Park=0; config.park_id[c.Park].checked=true; config.cond_id[c.CondR1].checked=true; config.mul_id[c.multiplier].checked=true; for (n in config.multable) if (config.multable[n] > c.multiplier) config.changeInstruction(false,n); if (c.PC_length<3) c.PC_length=3; if (c.PC_length>c.datapath) c.PC_length=c.datapath; config.PCwidth_id.innerHTML =config.PCwidth_id.source =c.PC_length; }, //////////////////////// generate the file //////////////////////// emit_VHDL: function(){ config.check(); var line, col, cvi, c=config.core, f, i, n, t, j, index, instr, vhdl=generated("--","VHDL/config.js") +'-- Profile name : '+config.name_id.innerHTML+'\n' +'\n' +'Library ieee;\n' +' use ieee.std_logic_1164.all;\n' +' use ieee.numeric_std.all;\n' +'\n' +'package yasep_definitions is\n' +'----------------------------------------------------------\n' +'-- user defined values :\n' +' constant YASEP_SIZE : natural := '+c.datapath+';\n' +' constant YASEP_MUL : natural := '+c.multiplier+';\n' //+'constant PIPELINED : natural := '+config.core.pipelined+';\n' +' constant Enable_CondR1 : natural := '+c.CondR1+';\n' +' constant Enable_Parking : natural := '+c.Park+';\n' +' constant PC_LENGTH : natural := ', valid_instructions=[], noWriteBack=[], noCondition=[], IMM_5LSB=[], abortWrite=[], IgnoreSND=[], IgnoreSI4=[], IgnoreImm16=[], ChangeCarry=[], Imm20=[], ChangeZero=[]; if (typeof c.PC_length =="number") vhdl+=c.PC_length; else vhdl+='YASEP_SIZE'; vhdl+=';\n\n' +'----------------------------------------------------------\n' +'-- exported from the JavaScript definitions :\n\n' +' subtype SLV2 is std_logic_vector( 1 downto 0);\n' +' subtype SLV3 is std_logic_vector( 2 downto 0);\n' +' subtype SLV4 is std_logic_vector( 3 downto 0);\n' +' subtype SLV5 is std_logic_vector( 4 downto 0);\n' +' subtype SLV6 is std_logic_vector( 5 downto 0);\n' +' subtype SLV8 is std_logic_vector( 7 downto 0);\n' +' subtype SLV16 is std_logic_vector(15 downto 0);\n' +' subtype SLV32 is std_logic_vector(31 downto 0);\n' +' subtype SLVr64 is std_logic_vector(0 to 63);\n' +' subtype SLVY is std_logic_vector(YASEP_SIZE-1 downto 0);\n' +' subtype SLVAI is std_logic_vector(PC_LENGTH-1 downto 1);\n\n'; for (i=0; i<16; i++) { t=Y.registers_names[i]; vhdl+=' constant REG_'+pad_right(t,4) + ': SLV4 := "'+toBin(i,4)+'";\n'; } vhdl+='\n'; for (line=0; line<32; line+=4) { // group number t=Y.GroupNames[line]; if (typeof t=="string") { vhdl+=" constant "+t; i=t.length; while (i<10) { i++; vhdl+=' '; } vhdl+=' : SLV3 := "'+toBin(line>>2,3)+'";\n'; } for (col=0; col<8; col++) { index=line|(col<<5); instr=Y.opcode_table[index]; if (typeof instr == 'object') { n=instr.name; i=index>>2; f=instr.flags; if (c.valid_instructions[n]===1) { valid_instructions[i]=1; if(f & Y.NO_WRITEBACK) noWriteBack[i]=1; if(f & Y.NO_CONDITION) noCondition[i]=1; if(f & Y.IMM16_5LSB) IMM_5LSB[i]=1; if(f & Y.ABORT_WRITE) abortWrite[i]=1; if(f & Y.IGNORE_SND) IgnoreSND[i]=1; if(f & Y.IGNORE_SI4) IgnoreSI4[i]=1; if(f & Y.IGNORE_IMM16) IgnoreImm16[i]=1; if(f & Y.CHANGE_CARRY) ChangeCarry[i]=1; if(f & Y.CHANGE_ZERO) ChangeZero[i]=1; if((f & Y.IMM20) && (config.core.datapath==32)) Imm20[i]=1; } vhdl+=' constant Op_'+n; f=n.length; while (f<7) { f++; vhdl+=' '; } vhdl+=' : SLV6 := "'+toBin(i,6)+'";' +' constant F_'+n; f=n.length; while (f<6) { f++; vhdl+=' '; } vhdl+=' : SLV3 := "'+toBin(i>>3,3)+'";'; if (c.valid_instructions[n]!==1) vhdl+=' -- disabled' ; vhdl+='\n'; } } vhdl+='\n'; } vhdl+='\n-- Flags :\n' + ' constant FlagValidInstruction : SLVr64 := "'+(cvi=collapse(valid_instructions)) // Export the valid_instructions field in hexa, for incorporating // later in the profiles collection of core-js/yasep_profiles.js: +'";\n-- Compacted mask: '+encodeInstructionMask(cvi) + ';\n constant FlagNoWriteBack : SLVr64 := "'+collapse(noWriteBack) +'";\n constant FlagNoCondition : SLVr64 := "'+collapse(noCondition) +'";\n constant FlagIMM16_5LSB : SLVr64 := "'+collapse(IMM_5LSB) +'";\n constant FlagAbortWrite : SLVr64 := "'+collapse(abortWrite) +'";\n constant FlagIgnoreSND : SLVr64 := "'+collapse(IgnoreSND) +'";\n constant FlagIgnoreSI4 : SLVr64 := "'+collapse(IgnoreSI4) +'";\n constant FlagIgnoreImm16 : SLVr64 := "'+collapse(IgnoreImm16) +'";\n constant FlagChangeCarry : SLVr64 := "'+collapse(ChangeCarry) +'";\n constant FlagChangeZero : SLVr64 := "'+collapse(ChangeZero) +'";\n constant FlagImm20 : SLVr64 := "'+collapse(Imm20) +'";\n' +'end yasep_definitions;\n' +'\n' +'package body yasep_definitions is\n' +' -- empty\n' +'end yasep_definitions;\n'; savefile.save("yasep_def.vhdl", vhdl); }, //////////////////////////////////////////////////////////////////////// changeRadio: function() { config.trigger(this.name+"="+this.value); }, // yeah, it's a compact trick, but a simple one :-) trigger: function(s) { if (s=="") return; if (s=="emitVHDL") return config.emit_VHDL(); var i,j=0,u,v; s=s.split(','); for (i in s){ u=s[i].split("="); if (u.length==2) { v=u[0]; if (v=="name") { if (j) // !=0 return alert("Malformed configuration request: the profile name must be the first parameter"); else config.change_profile(u[1]); } else if (typeof config.core[v]=="number") config.core[v]=+u[1]; j++; config.check(); } else return alert("Malformed configuration request : missing argument ?"); } }, AddProfile: function() { // config.nameInput_id.style.display="none"; }, change_profile: function(a) { if (typeof profiles[a] != "object") return Al8N("Ipn"); config.name_id.innerHTML=a; config.empty=(a=="empty"); config.block_id.style.display="block"; var n, p=profiles[a]; // manually copies the sub-objects config.core={ multiplier:p.multiplier, PC_length:p.PC_length, valid_instructions:[], // p.valid_instructions, => updated in changeInstruction datapath:p.datapath, CondR1:p.CondR1, Park:p.Park }; for (n in config.opcodes_id) config.changeInstruction( p.valid_instructions[n]===1, n, true); }, list_profiles: function(){ var l=config.list_div, p, d=dcE("div"), m="
"+profiles[p].comment+" |