/******************************************************************************* * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package hr.fer.zemris.vhdllab.service.extractor.automaton; import hr.fer.zemris.vhdllab.applets.editor.automaton.AUTPodatci; import hr.fer.zemris.vhdllab.applets.editor.automaton.Prijelaz; import hr.fer.zemris.vhdllab.applets.editor.automaton.Stanje; import java.util.HashSet; import java.util.LinkedList; import java.util.TreeSet; //TODO ako je samo std_logic da ne pise a(0) OK public class MooreParser implements IAutomatVHDLGenerator { private LinkedList<Stanje> stanja; private HashSet<Prijelaz> prijelazi; private AUTPodatci podatci; private LinkedList<Signal> ulazniSignali=new LinkedList<Signal>(); private LinkedList<Signal> izlazniSignali=new LinkedList<Signal>(); private String data=""; public MooreParser(LinkedList<Stanje> stanja, AUTPodatci podatci, HashSet<Prijelaz> prijelazi) { this.stanja=stanja; this.podatci=podatci; this.prijelazi=prijelazi; unparseEntity(); createData(); } private void createData() { StringBuffer buffer=new StringBuffer(); buffer.append("library IEEE;\nuse IEEE.STD_LOGIC_1164.ALL;\n\n"); buffer=addEntity(buffer); buffer.append("\nARCHITECTURE Behavioral OF ").append(podatci.ime).append(" IS\n"); buffer=createType(buffer); buffer.append("\nBEGIN\n"); buffer=createBlok1(buffer); buffer=createBlok2(buffer); buffer=createBlok3(buffer); buffer.append("\nEND Behavioral;"); data=buffer.toString(); } private StringBuffer createBlok3(StringBuffer buffer) { buffer.append("PROCESS(clock, reset)\nBEGIN\n\t") .append("IF reset='").append(podatci.reset).append("' THEN\n\t\tstate_present <= ST_") .append(podatci.pocetnoStanje).append(";\n\t") .append("ELSIF "); if(podatci.clock.equalsIgnoreCase("falling_edge"))buffer.append("falling_edge(clock)"); else if(podatci.clock.equalsIgnoreCase("rising_edge"))buffer.append("rising_edge(clock)"); else buffer.append("clock=").append(podatci.clock); buffer.append(" THEN\n\t\t") .append("state_present <= state_next;\n\tEND IF;\n") .append("END PROCESS;\n"); return buffer; } private StringBuffer createBlok2(StringBuffer buffer) { buffer.append("PROCESS(state_present)\nBEGIN\n\t") .append("CASE state_present IS"); for(Stanje st:stanja){ buffer.append("\n\tWHEN ST_" ).append(st.ime).append(" =>"); buffer=generirajIzlaze(st,buffer); } buffer.append("\n\tWHEN OTHERS => "); buffer=generirajIzlaze(null,buffer); buffer.append("\n\tEND CASE;\nEND PROCESS;\n"); return buffer; } private StringBuffer generirajIzlaze(Stanje st, StringBuffer buffer) { String izlaz=""; if(st==null){ StringBuffer b1=new StringBuffer(); for(int i=0;i<podatci.sirinaIzlaza;i++)b1.append("0"); izlaz=b1.toString(); }else izlaz=st.izlaz; buffer.append("\n\t\t"); int pozicija=0; for(Signal sig:izlazniSignali){ String navodnici=(sig.getTip()==Signal.STD_LOGIC_VECTOR?"\"":"'"); buffer.append(sig.getImeSignala()).append(" <= ").append(navodnici) .append(izlaz.substring(pozicija,pozicija+sig.getSirinaSignala())) .append(navodnici).append(";\n\t\t"); pozicija+=sig.getSirinaSignala(); } buffer.deleteCharAt(buffer.length()-1); buffer.deleteCharAt(buffer.length()-1); buffer.deleteCharAt(buffer.length()-1); return buffer; } private StringBuffer createBlok1(StringBuffer buffer) { buffer.append("PROCESS(state_present"); for (Signal ul:ulazniSignali)buffer.append(", ").append(ul.getImeSignala()); buffer.append(")\nBEGIN\n\tCASE state_present IS"); for(Stanje st:stanja){ buffer.append("\n\t\tWHEN ST_").append(st.ime).append("=>\n\t\t"); boolean test=true; for(Prijelaz pr:prijelazi) if(pr.iz.equals(st.ime)){ buffer.append(test?"IF ":"ELSIF "); test=false; buffer=generirajPrijelaz(buffer,pr); } if(!test)buffer.append("ELSE "); buffer.append("state_next<=ST_").append(st.els).append(";"); if(!test)buffer.append("\n\t\tEND IF;"); } buffer.append("\n\t\tWHEN OTHERS => state_next <= state_present;\n\tEND CASE;\nEND PROCESS;\n"); return buffer; } private StringBuffer generirajPrijelaz(StringBuffer buffer, Prijelaz pr) { buffer=createCondition(buffer,pr.pobudaIzlaz); buffer.append(" THEN state_next<=ST_").append(pr.u).append(";\n\t\t"); return buffer; } private StringBuffer createCondition(StringBuffer buffer, TreeSet<String> pobudaIzlaz) { for(String pom:pobudaIzlaz){ buffer.append("("); int broj=0; for(Signal sig:ulazniSignali){ buffer=createCplxCondition(buffer,sig,pom.substring(broj,broj+sig.getSirinaSignala())); broj+=sig.getSirinaSignala(); } buffer.deleteCharAt(buffer.length()-1); buffer.deleteCharAt(buffer.length()-1); buffer.deleteCharAt(buffer.length()-1); buffer.deleteCharAt(buffer.length()-1); buffer.append(")").append(" OR "); } buffer.deleteCharAt(buffer.length()-1); buffer.deleteCharAt(buffer.length()-1); buffer.deleteCharAt(buffer.length()-1); return buffer; } private StringBuffer createCplxCondition(StringBuffer buffer, Signal sig, String pom) { String navodnici=(sig.getTip()==Signal.STD_LOGIC?"'":"\""); StringBuffer pombuf=buffer; for(int i=0;i<pom.length();i++) if(pom.charAt(i)!='-'){ buffer.append(sig.getImeSignala()); if(sig.getTip()==Signal.STD_LOGIC_VECTOR) buffer.append("(").append(sig.getFrom()+sig.getSmijer()*i).append(")"); buffer.append("=").append(navodnici).append(pom.charAt(i)) .append(navodnici).append(" AND "); } /*if(!pom.matches(".*[-].*")) { pombuf.append(sig.getImeSignala()).append("=").append(navodnici).append(pom) .append(navodnici).append(" AND "); } else{ int state=0; int start=0; for(int i=0;i<pom.length();i++){ if(state==0) if(pom.charAt(i)=='0'||pom.charAt(i)=='1'){ start=i; state=1; } if(state==1) if(pom.charAt(i)=='-'){ buffer.append(sig.getImeSignala()); buffer.append("(").append(start).append(" TO ").append(i-1).append(")"); buffer.append("=").append(navodnici).append(pom.substring(start,i)) .append(navodnici).append(" AND "); state=0; } } if (state==1){ buffer.append(sig.getImeSignala()); buffer.append("(").append(start).append(" TO ").append(pom.length()-1).append(")"); buffer.append("=").append(navodnici).append(pom.substring(start,pom.length())) .append(navodnici).append(" AND "); } } */ return pombuf; } private StringBuffer createType(StringBuffer buffer) { //buffer.append("TYPE stateType IS ("); //for(Stanje st:stanja)buffer.append("ST_").append(st.ime).append(", "); //buffer.deleteCharAt(buffer.length()-1); //buffer.deleteCharAt(buffer.length()-1); //buffer.append(");\nSIGNAL state_present, state_next:stateType;\n"); Signal state = createStateSignal(); StringBuffer bufferTemp = new StringBuffer(); if(state.getTip()==Signal.STD_LOGIC){ bufferTemp.append(" std_logic"); }else{ bufferTemp.append(" std_logic_vector(").append(state.getFrom()) .append(state.getSmijer()==Signal.C_TO?" TO ":" DOWNTO ").append(state.getTo()).append(")"); } String stateType = bufferTemp.toString(); for(Stanje st:stanja){ buffer.append("\n CONSTANT ST_").append(st.ime).append(": ").append(stateType).append(" := ") .append(decToBinString(state.getTip(), stanja.indexOf(st), state.getFrom()+1)).append(";"); } buffer.append("\n"); buffer.append("\n SIGNAL state_present, state_next: ").append(stateType).append(";"); buffer.append("\n"); return buffer; } private String decToBinString(int tip, int indexOf, int size) { if(tip == Signal.STD_LOGIC){ return indexOf == 1?"'1'":"'0'"; } StringBuffer b = new StringBuffer("\""); for(int i = 0; i < size;i++){ b.append(indexOf%2); indexOf/=2; } return b.append("\"").reverse().toString(); } private Signal createStateSignal() { int length = stanja.size(); String tip = "std_logic"; int from = 0; int to = 0; if(length>2){ tip = "std_logic_vector"; from = (int) Math.floor(Math.log(length-1)/Math.log(2)); to = 0; } Signal s = new Signal(from,to,"signal",tip); return s; } private StringBuffer addEntity(StringBuffer buffer) { buffer.append("ENTITY ").append(podatci.ime).append(" IS PORT(\n") .append("\tclock: IN std_logic;\n\treset: IN std_logic;"); String[] redovi=podatci.interfac.split("\n"); for(int i=0;i<redovi.length;i++){ buffer.append("\n\t"); String[] rijeci=redovi[i].split(" "); buffer.append(rijeci[0]).append(": ").append(rijeci[1].toUpperCase()) .append(" ").append(rijeci[2]); if(rijeci[2].toUpperCase().equals("STD_LOGIC_VECTOR")){ if(Integer.parseInt(rijeci[3])<Integer.parseInt(rijeci[4])) buffer.append("(").append(Integer.parseInt(rijeci[3])).append(" TO ").append(Integer.parseInt(rijeci[4])).append(")"); else buffer.append("(").append(Integer.parseInt(rijeci[3])).append(" DOWNTO ").append(Integer.parseInt(rijeci[4])).append(")"); } buffer.append(";"); } buffer.deleteCharAt(buffer.length()-1); buffer.append(");\nEND ").append(podatci.ime).append(";\n"); return buffer; } private void unparseEntity() { String[] redovi=podatci.interfac.split("\n"); podatci.sirinaIzlaza=0; podatci.sirinaUlaza=0; for(int i=0;i<redovi.length;i++){ String[] pom=redovi[i].split(" "); int br=1; int odKud=0; int doKud=0; if(pom[2].toUpperCase().equals("STD_LOGIC_VECTOR")){ odKud=Integer.parseInt(pom[3]); doKud=Integer.parseInt(pom[4]); br+=Math.abs(odKud-doKud); } if(pom[1].toUpperCase().equals("IN"))podatci.sirinaUlaza+=br; else if(pom[1].toUpperCase().equals("OUT"))podatci.sirinaIzlaza+=br; if(pom[1].toUpperCase().equals("IN")){ ulazniSignali.add(new Signal(odKud,doKud,pom[0],pom[2])); }else { izlazniSignali.add(new Signal(odKud,doKud,pom[0],pom[2])); } } } public String getData() { return data; } }