Micro Fabric Demo Project

The Demo Folder includes a project in the "3MicroFabric" folder.

This project demonstrates the scripting of custom microcontrollers using Rapid HDL.

The microcontroller can be scripted using 2 options:

#an XML File
#c# code

XML Defined

The ToplevelHardware.cs file can be adjusted to use either XML or c# to generate a custom microprocessor.

The configuration to use XML is shown below..

        public override bool GenerateStructure(TopLevelComponent TopLevelComponent)
        {
            // Interfaces
            TopLevelComponent.SDRAMInterface.Enabled = false;
            TopLevelComponent.FIFOInterface.Enabled = true;
            //TopLevelComponent.TestBusWrite.Join(0);


            // DATA FLOW
            PipelineBuffer oInBuffer = new PipelineBuffer(TopLevelComponent, "in_buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 18, 4);
            oInBuffer.InputBus.Join(TopLevelComponent.FIFOInterface.BusFromExternal);
            PipelineSerialAssembler oAssembler = new PipelineSerialAssembler(TopLevelComponent, "assembler", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 18, 16, 2, 4);
            oAssembler.InputBus.Join(oInBuffer.OutputBus);

            PipelineBuffer oPCFPGABuffer = new PipelineBuffer(TopLevelComponent, "pc_fpga_buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 64, 1);
            oPCFPGABuffer.InputBus.Join(oAssembler.OutputBus);

            PipelineBuffer oFPGAPCBuffer = new PipelineBuffer(TopLevelComponent, "fpga_pc", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 42, 2);

            PipelineBuffer oPCOutBuffer = new PipelineBuffer(TopLevelComponent, "sdram_buffer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 42, 4);
            oPCOutBuffer.InputBus.Join(oFPGAPCBuffer.OutputBus);

            PipelineSerializer oSerializer = new PipelineSerializer(TopLevelComponent, "serializer", TopLevelComponent.MainClock, TopLevelComponent.MainReset, 42, 14);
            oSerializer.InputBus.Join(oPCOutBuffer.OutputBus);
            oSerializer.OutputBus.Join(TopLevelComponent.FIFOInterface.BusFromInternal);
            oSerializer.OffsetAddress = true;

            //oFabric = new QuickFabric(TopLevelComponent, "quick_fabric", TopLevelComponent.MainClock, TopLevelComponent.MainReset);
            oFabric = new RapidHDL.Fabric.XMLCore(TopLevelComponent, "quick_fabric", TopLevelComponent.MainClock, TopLevelComponent.MainReset, "c:\\src\\ESL\\fabric.xml");

            oFabric.InputBuses["EQI"].Join(oPCFPGABuffer.OutputBus);
            oFabric.OutputBuses["EQO"].Join(oFPGAPCBuffer.InputBus);

            return true;
        }

The XML file that defines the microprocessor is listed below.

<RapidHardware>
	<ExternalBusInput Name="EQI" Width="64" />
	<ExternalBusOutput Name="EQO" Width="42" />
	<!-- Registers and Operators -->
	<Register Name="A" Width="32" />
	<Register Name="B" Width="32" />
	<ALU Name="ADD" Width="32" Type="Add" />
	<ALU Name="AND" Width="32" Type="AndMask" />
	<!-- Equality Bit -->
	<Register Name="SR" Width="1" />
	<LogicBlock Name="EQ" Expression="IN1{32} = IN2{32}"/>
	<Join From="EQ.OUT" To="SR.IN" />
	<StatusOutput Name="EQ" From="SR.OUT" />
	<!-- Stack -->
	<RAM Name="STACK" Width="32" Depth="12" />
	<Register Name="SP" Width="6" />
	<ALU Name="SP_INC" Width="6" Type="INC" />
	<ALU Name="SP_DEC" Width="6" Type="DEC" />
	<Join From="SP.OUT" To="STACK.ADDRESS" />
	<Join From="SP.OUT" To="SP_INC.IN1" />
	<Join From="SP.OUT" To="SP_DEC.IN1" />


	<!-- Basic Constants -->
	<Constant Name="ZERO" Value="0" Width="32" />
	<Constant Name="ZERO_BIT" Value="0" Width="1" />
	<Constant Name="ONE_BIT" Value="1" Width="1" />

	<!-- External FIFO Interface -->
	<Register Name="QI" Width="32" />
	<Register Name="QT" Width="6" />
	<Register Name="QO" Width="32" />
	
	<BitCombine Name="E_OUT" InputWidths="32,2,6,1,1" />
	<Join From="E_OUT.OUT" To="EQO.IN" />
	<Join From="QO.OUT" To="E_OUT.IN1" />
	<Join From="ZERO.OUT" To="E_OUT.IN2" />
	<Join From="ZERO.OUT" To="E_OUT.IN3" />
	<Join From="ZERO_BIT.OUT" To="E_OUT.IN4" />

	<BitBreakout Name="E_IN" OutputWidths="32,24,6,1,1" />
	<Join From="EQI.OUT" To="E_IN.IN" />
	<Join From="E_IN.OUT1" To="QI.IN" />
	<Join From="E_IN.OUT3" To="QT.IN" />

	<Resize Name="QT_32" InputWidth="6" OutputWidth="32" />
	<Join From="QT.OUT" To="QT_32.IN" />
	
	<!-- Program Support -->
	<ProgramROMRAM  Name="PROG" ConstantWidth="32" RAMOffset="100" RAMDepth="50" ROMProgramPath="c:\quick_rom.rasm" RAMProgramPath="c:\quick_ram.rasm" ConstantRegister = "C" ProgramCounter = "PC">
		<MicroCore Name="CORE">
				<OpCode Name="JMP_EQI">
						<Branch Status="EQI_READY" ToLabel="EQI_READY" />
						<Jump ToLabel="EQI_NOT_READY" />
						<State ControlState="PC_JUMP" Label="EQI_READY" />
						<State ControlState="NOP" Label="EQI_NOT_READY" />
						<State ControlState="NOP"/>
						<State ControlState="NOP"/>
				</OpCode>


				<OpCode Name="BEQ">
						<Branch Status="EQ" ToLabel="JMP_0_EQ" />
						<Jump ToLabel="JMP_0_DONE" />
						<State ControlState="PC_JUMP" Label="JMP_0_EQ" />
						<State ControlState="NOP" Label="JMP_0_DONE" />
				</OpCode>

				<OpCode Name="JMP">
						<State ControlState="PC_JUMP" />
						<State ControlState="NOP" />
						<State ControlState="NOP" />
						<State ControlState="NOP" />
				</OpCode>

				<OpCode Name="PUSH_A">
						<State ControlState="PUSH_A" />
						<State ControlState="SP_INC" />
				</OpCode>
						
				<OpCode Name="PULL_A">
						<State ControlState="SP_DEC" />
						<State ControlState="NOP" />
						<State ControlState="NOP" />
						<State ControlState="PULL_A" />
				</OpCode>

				<OpCode Name="PUSH_B">
						<State ControlState="PUSH_B" />
						<State ControlState="SP_INC" />
				</OpCode>
						
				<OpCode Name="PULL_B">
						<State ControlState="SP_DEC" />
						<State ControlState="NOP" />
						<State ControlState="NOP" />
						<State ControlState="PULL_B" />
				</OpCode>

				<OpCode Name="PROGRAM">
						<State ControlState="PROGRAM" />
						<State ControlState="PROGRAM" />
						<State ControlState="PROGRAM" />
				</OpCode>

				<!-- NOP -->
				<ControlState Name="NOP" OpCode="true" />	
				<!-- LOAD_A_C -->
				<ControlState Name="LOAD_A_C" OpCode="true" >
					<Join From="C.OUT" To="A.IN" />
					<Activate Signal="A.LATCH" />
				</ControlState>
				<!-- LOAD_B_C -->
				<ControlState Name="LOAD_B_C" OpCode="true" >
					<Join From="C.OUT" To="B.IN" />
					<Activate Signal="B.LATCH" />
				</ControlState>
				<!-- PUSH_A -->
				<ControlState Name="PUSH_A">
					<Join From="A.OUT" To="STACK.DATA_IN" />
					<Activate Signal="STACK.WRITE" />
				</ControlState>
				<!-- PULL_A -->
				<ControlState Name="PULL_A">
					<Join From="STACK.DATA_OUT" To="A.IN" />
					<Activate Signal="A.LATCH" />
				</ControlState>
				<!-- PUSH_B -->
				<ControlState Name="PUSH_B">
					<Join From="B.OUT" To="STACK.DATA_IN" />
					<Activate Signal="STACK.WRITE" />
				</ControlState>
				<!-- PULL_B -->
				<ControlState Name="PULL_B">
					<Join From="STACK.DATA_OUT" To="B.IN" />
					<Activate Signal="B.LATCH" />
				</ControlState>
				<!-- LOAD_A_QI -->
				<ControlState Name="LOAD_A_QI"  OpCode="true" >
					<Join From="QI.OUT" To="A.IN" />
					<Activate Signal="A.LATCH" />
				</ControlState>
				<!-- LOAD_QO_A -->
				<ControlState Name="LOAD_QO_A"  OpCode="true" >
					<Join From="A.OUT" To="QO.IN" />
					<Activate Signal="QO.LATCH" />
				</ControlState>
				<!-- PC_INC -->
				<ControlState Name="PC_INC">
					<Join From="PC_INC.OUT" To="PC.IN" />
					<Activate Signal="PC.LATCH" />
					<Activate Signal="C.LATCH" />
				</ControlState>
				<!-- PC_JUMP -->
				<ControlState Name="PC_JUMP">
					<Join From="C.OUT" To="PC.IN" />
					<Activate Signal="PC.LATCH" />
				</ControlState>
				<!-- EQI_READ -->
				<ControlState Name="EQI_READ"  OpCode="true" >
					<Activate Signal="QI.LATCH" />
					<Activate Signal="QT.LATCH" />
					<Activate Signal="EQI.READ" />
				</ControlState>
				<!-- COMP_A_C -->
				<ControlState Name="COMP_A_C" OpCode="true" >
					<Join From="A.OUT" To="EQ.IN1" />
					<Join From="C.OUT" To="EQ.IN2" />
					<Activate Signal="SR.LATCH" />
				</ControlState>
				<!-- COMP_A_B -->
				<ControlState Name="COMP_A_B"  OpCode="true" >
					<Join From="A.OUT" To="EQ.IN1" />
					<Join From="B.OUT" To="EQ.IN2" />
					<Activate Signal="SR.LATCH" />
				</ControlState>
				<!-- ADD_A_C -->
				<ControlState Name="ADD_A_C"  OpCode="true" >
					<Join From="A.OUT" To="ADD.IN1" />
					<Join From="C.OUT" To="ADD.IN2" />
					<Join From="ADD.OUT" To="A.IN" />
					<Activate Signal="A.LATCH" />
				</ControlState>
				<!-- ADD_A_B -->
				<ControlState Name="ADD_A_B"  OpCode="true" >
					<Join From="A.OUT" To="ADD.IN1" />
					<Join From="B.OUT" To="ADD.IN2" />
					<Join From="ADD.OUT" To="A.IN" />
					<Activate Signal="A.LATCH" />
				</ControlState>
				<!-- EQO_POST -->
				<ControlState Name="EQO_POST"  OpCode="true" >
					<Activate Signal="EQO.LATCH" />
				</ControlState>
				<!-- SP_INC -->
				<ControlState Name="SP_INC">
					<Join From="SP_INC.OUT" To="SP.IN" />
					<Activate Signal="SP.LATCH" />
				</ControlState>
				<!-- SP_DEC -->
				<ControlState Name="SP_DEC">
					<Join From="SP_DEC.OUT" To="SP.IN" />
					<Activate Signal="SP.LATCH" />
				</ControlState>
				<!-- A_AND_B -->
				<ControlState Name="A_AND_B">
					<Join From="A.OUT" To="AND.IN1" />
					<Join From="B.OUT" To="AND.IN2" />
					<Activate Signal="A.LATCH" />
				</ControlState>
				<!-- PROGRAM -->
				<ControlState Name="PROGRAM">
					<Activate Signal="PROG.PROGRAM" />
				</ControlState>
				<!-- COMP_QT_C -->
				<ControlState Name="COMP_QT_C"  OpCode="true" >
					<Join From="QT_32.OUT" To="EQ.IN1" />
					<Join From="C.OUT" To="EQ.IN2" />
					<Activate Signal="SR.LATCH" />
				</ControlState>

		</MicroCore>
	</ProgramROMRAM>	


	<Join From="A.OUT" To="PROG.IR" />
	<Join From="B.OUT" To="PROG.CONST" />
	<Join From="QI.OUT" To="PROG.ADDRESS" />
</RapidHardware>

C# defined

To use C# to define the exact same microcontroller, the following line needs to be changed in ToplevelHardware.cs.

            oFabric = new QuickFabric(TopLevelComponent, "quick_fabric", TopLevelComponent.MainClock, TopLevelComponent.MainReset);
            //oFabric = new RapidHDL.Fabric.XMLCore(TopLevelComponent, "quick_fabric", TopLevelComponent.MainClock, TopLevelComponent.MainReset, "c:\\src\\ESL\\fabric.xml");

In addition, the following files need to be added to the project...

QuickFabric.cs

using System;
using System.Collections.Generic;
using System.Text;
using RapidHDL;

namespace MicroFabric
{
    public class QuickFabric : FabricComponent
    {
        int iPCWidth;
        int iConstWidth;
        int iIRWidth;

        RapidHDL.Fabric.MicroCoreBlock  oMicroCore;
        RapidHDL.Fabric.ProgramROMRAMBlock oProgram;
        MicroCoreTable oCoreTable;

        public QuickFabric(Component poParentComponent, string psName, ClockComponent poClock, NodeVector pnvReset)
            : base(poParentComponent, psName, poClock, pnvReset)
        {
        }


        public override void DefineFabric()
        {
            ContainerBlock.CreateExternalBusInput("EQI", 64);
            ContainerBlock.CreateExternalBusOutput("EQO", 42);

            //Registers and Operators
            ContainerBlock.CreateRegister("A", 32, true);
            ContainerBlock.CreateRegister("B", 32, true);

            ContainerBlock.CreateALU("ADD", ALUType.Add, 32);
            ContainerBlock.CreateALU("AND", ALUType.AndMask, 32);

            // Equality Status Bit
            ContainerBlock.CreateRegister("SR", 1, true);
            ContainerBlock.CreateLogicBlock("EQ", "IN1<32> = IN2<32>");
            ContainerBlock.Join("EQ", "OUT", "SR", "IN");
            ContainerBlock.CreateStatusOutput("EQ", "SR", "OUT");

            //STACK
            ContainerBlock.CreateRAM("STACK", 32, 12, true);// should be bigger to be safe
            ContainerBlock.CreateRegister("SP", 6, true);
            ContainerBlock.CreateALU("SP_INC", ALUType.Inc, 6);
            ContainerBlock.CreateALU("SP_DEC", ALUType.Dec, 6);
            ContainerBlock.Join("SP", "OUT", "STACK", "ADDRESS");
            ContainerBlock.Join("SP", "OUT", "SP_INC", "IN1");
            ContainerBlock.Join("SP", "OUT", "SP_DEC", "IN1");


            // Program Core
            string sROMProgramPath = "c:\\quick_rom.rasm";
            //string sROMProgramPath = "c:\\rom.rasm";
            string sRAMProgramPath = "c:\\quick_ram.rasm";
            //string sRAMProgramPath = "c:\\x.rasm";
            oCoreTable = new QuickFabricTable();
            oMicroCore = ContainerBlock.CreateMicroCore("CORE", oCoreTable);
            oProgram = ContainerBlock.CreateProgramROMRAM("PROG", oCoreTable, sROMProgramPath, sRAMProgramPath, 100, 50, 32);

            iPCWidth = oProgram.Inputs["PC"].Width;
            iConstWidth = oProgram.Outputs["CONST"].Width;
            iIRWidth = oProgram.Outputs["IR"].Width;

            ContainerBlock.CreateRegister("C", 32, true);
            ContainerBlock.CreateRegister("PC", iPCWidth, true);
            ContainerBlock.CreateALU("PC_INC", ALUType.Inc, iPCWidth);

            ContainerBlock.Join("PROG", "CONST", "C", "IN");
            ContainerBlock.Join("PC", "OUT", "PC_INC", "IN1");
            ContainerBlock.Join("PROG", "IR", "CORE", "IR");
            ContainerBlock.Join("PC", "OUT", "PROG", "PC");


            // Basic Constants
            ContainerBlock.CreateConstant("ZERO", 0, 32);
            ContainerBlock.CreateConstant("ZERO_BIT", 0, 1);
            ContainerBlock.CreateConstant("ONE_BIT", 1, 1);


            //External FIFO Interface

            ContainerBlock.CreateRegister("QI", 32, true);
            ContainerBlock.CreateRegister("QT", 6, true);
            ContainerBlock.CreateRegister("QO", 32, true);

            ContainerBlock.CreateCombine("E_OUT", 32, 2, 6, 1, 1);
            ContainerBlock.Join("E_OUT", "OUT", "EQO", "IN");
            ContainerBlock.Join("QO", "OUT", "E_OUT", "IN1");
            ContainerBlock.Join("ZERO", "OUT", "E_OUT", "IN2");
            ContainerBlock.Join("ZERO", "OUT", "E_OUT", "IN3");
            ContainerBlock.Join("ZERO_BIT", "OUT", "E_OUT", "IN4");

            ContainerBlock.CreateBreakout("E_IN", 32, 24, 6, 1, 1);
            ContainerBlock.Join("EQI", "OUT", "E_IN", "IN");
            ContainerBlock.Join("E_IN", "OUT1", "QI", "IN");
            ContainerBlock.Join("E_IN", "OUT3", "QT", "IN");

            ContainerBlock.CreateResize("QT_32", 6, 32);
            ContainerBlock.Join("QT", "OUT", "QT_32", "IN");


            ContainerBlock.Join("A", "OUT", "PROG", "IR");
            ContainerBlock.Join("B", "OUT", "PROG", "CONST");
            ContainerBlock.Join("QI", "OUT", "PROG", "ADDRESS");


            DefineControlStates();
        }

        public void DefineControlStates()
        {
            //NOP
            RapidHDL.Fabric.ControlState oControl = ContainerBlock.CreateControlState("NOP");

            //LOAD_A_C
            oControl = ContainerBlock.CreateControlState("LOAD_A_C");
            oControl.Join("C", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //LOAD_B_C
            oControl = ContainerBlock.CreateControlState("LOAD_B_C");
            oControl.Join("C", "OUT", "B", "IN");
            oControl.Activate("B", "LATCH");

            //PUSH_A
            oControl = ContainerBlock.CreateControlState("PUSH_A");
            oControl.Join("A", "OUT", "STACK", "DATA_IN");
            oControl.Activate("STACK", "WRITE");

            //PULL_A
            oControl = ContainerBlock.CreateControlState("PULL_A");
            oControl.Join("STACK", "DATA_OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //PUSH_B
            oControl = ContainerBlock.CreateControlState("PUSH_B");
            oControl.Join("B", "OUT", "STACK", "DATA_IN");
            oControl.Activate("STACK", "WRITE");

            //PULL_A
            oControl = ContainerBlock.CreateControlState("PULL_B");
            oControl.Join("STACK", "DATA_OUT", "B", "IN");
            oControl.Activate("B", "LATCH");


            //LOAD_A_QI
            oControl = ContainerBlock.CreateControlState("LOAD_A_QI");
            oControl.Join("QI", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //LOAD_QO_A
            oControl = ContainerBlock.CreateControlState("LOAD_QO_A");
            oControl.Join("A", "OUT", "QO", "IN");
            oControl.Activate("QO", "LATCH");

            //PC_INC
            oControl = ContainerBlock.CreateControlState("PC_INC");
            oControl.Join("PC_INC", "OUT", "PC", "IN");
            oControl.Activate("PC", "LATCH");
            oControl.Activate("C", "LATCH");

            //PC_JUMP
            oControl = ContainerBlock.CreateControlState("PC_JUMP");
            oControl.Join("C", "OUT", "PC", "IN");
            oControl.Activate("PC", "LATCH");

            //EQI_READ
            oControl = ContainerBlock.CreateControlState("EQI_READ");
            oControl.Activate("QI", "LATCH");
            oControl.Activate("QT", "LATCH");
            oControl.Activate("EQI", "READ");

            //COMP_A_C
            oControl = ContainerBlock.CreateControlState("COMP_A_C");
            oControl.Join("A", "OUT", "EQ", "IN1");
            oControl.Join("C", "OUT", "EQ", "IN2");
            oControl.Activate("SR", "LATCH");

            //COMP_A_B
            oControl = ContainerBlock.CreateControlState("COMP_A_B");
            oControl.Join("A", "OUT", "EQ", "IN1");
            oControl.Join("B", "OUT", "EQ", "IN2");
            oControl.Activate("SR", "LATCH");

            //ADD_A_C
            oControl = ContainerBlock.CreateControlState("ADD_A_C");
            oControl.Join("A", "OUT", "ADD", "IN1");
            oControl.Join("C", "OUT", "ADD", "IN2");
            oControl.Join("ADD", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //ADD_A_B
            oControl = ContainerBlock.CreateControlState("ADD_A_B");
            oControl.Join("A", "OUT", "ADD", "IN1");
            oControl.Join("B", "OUT", "ADD", "IN2");
            oControl.Join("ADD", "OUT", "A", "IN");
            oControl.Activate("A", "LATCH");

            //EQO_POST
            oControl = ContainerBlock.CreateControlState("EQO_POST");
            oControl.Activate("EQO", "LATCH");

            //SP_INC
            oControl = ContainerBlock.CreateControlState("SP_INC");
            oControl.Join("SP_INC", "OUT", "SP", "IN");
            oControl.Activate("SP", "LATCH");

            //SP_DEC
            oControl = ContainerBlock.CreateControlState("SP_DEC");
            oControl.Join("SP_DEC", "OUT", "SP", "IN");
            oControl.Activate("SP", "LATCH");

            //A_AND_B
            oControl = ContainerBlock.CreateControlState("A_AND_B");
            oControl.Join("A", "OUT", "AND", "IN1");
            oControl.Join("B", "OUT", "AND", "IN2");
            oControl.Activate("A", "LATCH");

            //PROGRAM
            oControl = ContainerBlock.CreateControlState("PROGRAM");
            oControl.Activate("PROG", "PROGRAM");

            //COMP_QT_C
            oControl = ContainerBlock.CreateControlState("COMP_QT_C");
            oControl.Join("QT_32", "OUT", "EQ", "IN1");
            oControl.Join("C", "OUT", "EQ", "IN2");
            oControl.Activate("SR", "LATCH");
        }


        public void AddSignalViews()
        {
            ContainerBlock.AddSignalView("A", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("B", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("SR", "OUT");
            ContainerBlock.AddSignalView("C", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("PROG", "IR", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("PC", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("QI", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("QO", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("SP", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("QT", "OUT", SignalFormat.Unsigned);
            ContainerBlock.AddSignalView("EQI", "OUT");
            ContainerBlock.AddSignalView("EQI", "READY");

            oMicroCore.AddSignalViews();
            oProgram.AddSignalViews();
        }

        public void SignalDisplay(HardwareScript poScript, int piClockTime)
        {
            ContainerBlock.SignalDisplay(poScript, piClockTime);
            oMicroCore.SignalDisplay(poScript, piClockTime);
            oProgram.SignalDisplay(poScript, piClockTime);
        }

        public string GetProgramText()
        {
            return oProgram.GetProgramText();
        }

        public Dictionary<int, int> GetProgramAddressToLine()
        {
            return oProgram.GetProgramAddressToLine();
        }

        public void LoadRAMProgram()
        {
            oProgram.LoadRAMProgram();
        }

        public List<string> GetOpCodes()
        {
            List<string> lResult = new List<string>();
            foreach (string sOpCode in oCoreTable.Ops.Keys)
                lResult.Add(sOpCode);

            return lResult;
        }

        public List<int> GetBreakpoints()
        {
            return oProgram.GetBreakpoints();
        }
    }
}

MicroCoreTable.cs

using System;
using System.Collections.Generic;
using System.Text;
using RapidHDL;

namespace _MicroFabric
{
    public class QuickFabricTable : MicroCoreTable
    {
        public QuickFabricTable()
            : base()
        {

            MicroCoreOp oOp;

            //Define Op Codes
            oOp = AddOp("JMP_EQI");
            oOp.AddBranchInstruction("EQI_READY", "EQI_READY");
            oOp.AddJumpInstruction("EQI_NOT_READY");
            oOp.AddStateInstruction("PC_JUMP", "EQI_READY");
            oOp.AddStateInstruction("NOP", "EQI_NOT_READY");
            oOp.AddStateInstruction("NOP");
            oOp.AddStateInstruction("NOP");

            oOp = AddOp("BEQ");
            oOp.AddBranchInstruction("EQ", "JMP_0_EQ");
            oOp.AddJumpInstruction("JMP_0_DONE");
            oOp.AddStateInstruction("PC_JUMP", "JMP_0_EQ");
            oOp.AddStateInstruction("NOP", "JMP_0_DONE");

            oOp = AddOp("JMP");
            oOp.AddStateInstruction("PC_JUMP");
            oOp.AddStateInstruction("NOP");
            oOp.AddStateInstruction("NOP");
            oOp.AddStateInstruction("NOP");

            oOp = AddOp("PUSH_A");
            oOp.AddStateInstruction("PUSH_A");
            oOp.AddStateInstruction("SP_INC");

            oOp = AddOp("PULL_A");
            oOp.AddStateInstruction("SP_DEC");
            oOp.AddStateInstruction("NOP");
            oOp.AddStateInstruction("NOP");
            oOp.AddStateInstruction("PULL_A");

            oOp = AddOp("PUSH_B");
            oOp.AddStateInstruction("PUSH_B");
            oOp.AddStateInstruction("SP_INC");

            oOp = AddOp("PULL_B");
            oOp.AddStateInstruction("SP_DEC");
            oOp.AddStateInstruction("NOP");
            oOp.AddStateInstruction("NOP");
            oOp.AddStateInstruction("PULL_B");

            oOp = AddOp("PROGRAM");
            oOp.AddStateInstruction("PROGRAM");
            oOp.AddStateInstruction("PROGRAM");
            oOp.AddStateInstruction("PROGRAM");

            AddSimpleOp("NOP");
            AddSimpleOp("LOAD_A_C");
            AddSimpleOp("LOAD_B_C");
            AddSimpleOp("LOAD_A_QI");
            AddSimpleOp("LOAD_QO_A");
            AddSimpleOp("EQI_READ");
            AddSimpleOp("COMP_A_C");
            AddSimpleOp("COMP_A_B");
            AddSimpleOp("ADD_A_C");
            AddSimpleOp("ADD_A_B");
            AddSimpleOp("EQO_POST");
            AddSimpleOp("COMP_QT_C");

        }

        public void AddSimpleOp(string psName)
        {
            MicroCoreOp oOp = AddOp(psName);
            oOp.AddStateInstruction(psName);
        }
    }
}

Assembly Test Files

quick_rom.rasm

NOP
LOAD_A_C 1
PUSH_A
PULL_B

wait_for_pc:
JMP_EQI pc_response_in  // loop until something in Q
JMP wait_for_pc
pc_response_in:
EQI_READ

COMP_QT_C 2
BEQ pc_loads_a

COMP_QT_C 3
BEQ pc_loads_b

COMP_QT_C 60
BEQ program_ram

COMP_QT_C 61
BEQ start_ram

JMP wait_for_pc

pc_loads_a:
LOAD_A_QI
JMP wait_for_pc

pc_loads_b:
PUSH_A
LOAD_A_QI
PUSH_A
PULL_B
PULL_A
JMP wait_for_pc

program_ram:
PROGRAM
JMP wait_for_pc

start_ram:
JMP 100

quick_ram.rasm

// Simple Routine
// Wait for 2 inputs
// Then Add Them and Send them Back

// store a 0 on the stack
NOP
LOAD_A_C 0
PUSH_A

wait_for_pc:
JMP_EQI pc_response_in  // loop until something in Q
JMP wait_for_pc
pc_response_in:
EQI_READ

LOAD_A_QI  // load from the input Q
PUSH_A  // transfer to B register
PULL_B

PULL_A
COMP_A_C 0
BEQ first_input  // if 0 is on the stack, then we want one more input

//otherwise, we have the second input
JMP second_input


first_input:
PUSH_B  // store the value we just got, on stack
LOAD_A_C 1 // store a 1 on the stack, to show we have 1 input
PUSH_A
JMP wait_for_pc  // wait for the next input


second_input:
PULL_A   // get the previous value from the stack
ADD_A_B  // now A has the sum of both

LOAD_QO_A
EQO_POST    // send the value from A to the external Q
LOAD_A_C 0
PUSH_A
JMP wait_for_pc  // do it all over again
NOP
NOP

Last edited Sep 11, 2009 at 7:42 AM by allen248, version 4

Comments

No comments yet.