ModelComponentToVerilogConverter can now convert TriStateBuffers
[Mograsim.git] / plugins / net.mograsim.logic.model.verilog / src / net / mograsim / logic / model / verilog / converter / components / TriStateBufferConverter.java
1 package net.mograsim.logic.model.verilog.converter.components;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import com.google.gson.JsonElement;
7
8 import net.mograsim.logic.core.types.Bit;
9 import net.mograsim.logic.core.types.BitVector;
10 import net.mograsim.logic.model.model.components.atomic.ModelTriStateBuffer;
11 import net.mograsim.logic.model.model.wires.Pin;
12 import net.mograsim.logic.model.verilog.converter.ComponentConversionResult;
13 import net.mograsim.logic.model.verilog.converter.ModelComponentToVerilogComponentDeclarationMapping;
14 import net.mograsim.logic.model.verilog.converter.ModelComponentToVerilogConverter;
15 import net.mograsim.logic.model.verilog.converter.PinNameBit;
16 import net.mograsim.logic.model.verilog.model.VerilogComponentDeclaration;
17 import net.mograsim.logic.model.verilog.model.VerilogComponentImplementation;
18 import net.mograsim.logic.model.verilog.model.expressions.Constant;
19 import net.mograsim.logic.model.verilog.model.expressions.Expression;
20 import net.mograsim.logic.model.verilog.model.expressions.SignalReference;
21 import net.mograsim.logic.model.verilog.model.signals.IOPort;
22 import net.mograsim.logic.model.verilog.model.signals.Input;
23 import net.mograsim.logic.model.verilog.model.signals.Output;
24 import net.mograsim.logic.model.verilog.model.signals.Wire;
25 import net.mograsim.logic.model.verilog.model.statements.Assign;
26 import net.mograsim.logic.model.verilog.model.statements.ComponentReference;
27 import net.mograsim.logic.model.verilog.model.statements.Statement;
28 import net.mograsim.logic.model.verilog.model.statements.WireDeclaration;
29 import net.mograsim.logic.model.verilog.utils.IdentifierGenerator;
30 import net.mograsim.logic.model.verilog.utils.UnionFind;
31
32 public class TriStateBufferConverter implements ComponentConverter<ModelTriStateBuffer>
33 {
34         // TODO don't hardcode this
35         private static final VerilogComponentDeclaration TSBW_COMBINE = new VerilogComponentDeclaration("tsbw_combine",
36                         List.of(new Input("wA", 2), new Input("wB", 2), new Output("res", 2)));
37         private static final VerilogComponentDeclaration TSBW_CONDITIONAL = new VerilogComponentDeclaration("tsbw_conditional",
38                         List.of(new Input("cond", 2), new Input("onTrue", 2), new Input("onFalse", 2), new Output("res", 2)));
39
40         private final ModelComponentToVerilogConverter converter;
41
42         public TriStateBufferConverter(ModelComponentToVerilogConverter converter)
43         {
44                 this.converter = converter;
45         }
46
47         @Override
48         public ComponentConversionResult convert(ModelTriStateBuffer modelComponent, String modelID, JsonElement params, String verilogID)
49         {
50                 UnionFind<PinNameBit> connectedPins = new UnionFind<>();
51                 ModelComponentToVerilogComponentDeclarationMapping mapping = ModelComponentToVerilogConverter
52                                 .generateCanonicalDeclarationMapping(modelComponent, connectedPins, modelID, params, verilogID);
53                 VerilogComponentDeclaration declaration = mapping.getVerilogComponentDeclaration();
54
55                 List<Statement> statements = new ArrayList<>();
56
57                 PinNameBit condPinbit = new PinNameBit(modelComponent.getEnablePin().name, 0);
58                 IOPort condPre = mapping.getPrePinMapping().get(condPinbit).getVerilogPort();
59                 IOPort condOut = mapping.getOutPinMapping().get(condPinbit).getVerilogPort();
60                 IOPort condRes = mapping.getResPinMapping().get(condPinbit).getVerilogPort();
61                 Expression condrResRef = new SignalReference(condRes);
62
63                 statements.add(new Assign(condOut, new SignalReference(condPre)));
64
65                 IdentifierGenerator idGen = ModelComponentToVerilogConverter.generateIdentifierGenerator(declaration);
66
67                 Pin inputPin = modelComponent.getInputPin();
68                 Pin outputPin = modelComponent.getOutputPin();
69                 for (int bit = 0; bit < inputPin.logicWidth; bit++)
70                 {
71                         PinNameBit inputPinbit = new PinNameBit(inputPin.name, bit);
72                         PinNameBit outputPinbit = new PinNameBit(outputPin.name, bit);
73
74                         IOPort inPre = mapping.getPrePinMapping().get(inputPinbit).getVerilogPort();
75                         IOPort inOut = mapping.getOutPinMapping().get(inputPinbit).getVerilogPort();
76                         IOPort inRes = mapping.getResPinMapping().get(inputPinbit).getVerilogPort();
77                         IOPort outPre = mapping.getPrePinMapping().get(outputPinbit).getVerilogPort();
78                         IOPort outOut = mapping.getOutPinMapping().get(outputPinbit).getVerilogPort();
79                         Expression inPreRef = new SignalReference(inPre);
80                         Expression inResRef = new SignalReference(inRes);
81                         Expression outPreRef = new SignalReference(outPre);
82                         Expression outOutRef = new SignalReference(outOut);
83
84                         Wire condTmp = new Wire(idGen.generateID("cond_tmp_" + bit), 2);
85                         SignalReference condTmpRef = new SignalReference(condTmp);
86                         statements.add(new WireDeclaration(condTmp));
87
88                         statements.add(new Assign(inOut, inPreRef));
89                         statements.add(new ComponentReference(idGen.generateID("cond_" + bit), TSBW_CONDITIONAL,
90                                         List.of(condrResRef, inResRef, new Constant(BitVector.of(Bit.ZERO, 2)), condTmpRef)));
91                         statements
92                                         .add(new ComponentReference(idGen.generateID("comb_" + bit), TSBW_COMBINE, List.of(outPreRef, condTmpRef, outOutRef)));
93                 }
94
95                 VerilogComponentImplementation implementation = new VerilogComponentImplementation(declaration, statements);
96
97                 return new ComponentConversionResult(mapping, implementation);
98         }
99 }