public SyncRAMInterfaceRW1R1(RAM ram) { this.RAM = ram; ReadCmd1_IFace = CreateInputface <ReadCommand>(); ReadCmd2_IFace = CreateInputface <ReadCommand>(); WriteCmd_IFace = CreateInputface <WriteCommand>(); ReadValue1_OFace = CreateSyncOutputface <uint>(); ReadValue2_OFace = CreateSyncOutputface <uint>(); }
public ApplyStage() { MemOp_IFace = CreateInputface <bool>(); MemRw_IFace = CreateInputface <bool>(); AluRes_IFace = CreateInputface <uint>(); RegRdataC_IFace = CreateInputface <uint>(); RegNoC_IFace = CreateInputface <byte>(); ValidAS_IFace = CreateInputface <bool>(); MemRdata_IFace = CreateInputface <uint>(); MemoryStallRequest_OFace = CreateAsyncOutputface <bool>(); MemEn_OFace = CreateAsyncOutputface <bool>(); MemAddr_OFace = CreateAsyncOutputface <uint>(); MemWen_OFace = CreateAsyncOutputface <bool>(); MemWdata_OFace = CreateAsyncOutputface <uint>(); RegWen_OFace = CreateAsyncOutputface <bool>(); RegWdata_OFace = CreateAsyncOutputface <uint>(); RegWno_OFace = CreateAsyncOutputface <byte>(); memReaded = CreateSyncOutputface <bool>(false); MemoryStallRequest_OFace.SetFunc(() => { return(ValidAS_IFace && !memReaded.Value && MemOp_IFace); }); MemEn_OFace.SetFunc(() => { return(!memReaded.Value); }); MemAddr_OFace.SetFunc(() => { return(AluRes_IFace);// >> 2; }); MemWen_OFace.SetFunc(() => { return(!memReaded.Value && MemRw_IFace); }); MemWdata_OFace.SetFunc(() => { return(RegRdataC_IFace); }); RegWen_OFace.SetFunc(() => { return(ValidAS_IFace && (!MemOp_IFace || (!MemRw_IFace && !memReaded.Value))); }); RegWdata_OFace.SetFunc(() => { return(MemOp_IFace ? MemRdata_IFace : AluRes_IFace); }); RegWno_OFace.SetFunc(() => { return(RegNoC_IFace); }); }
public FetchStage(bool delayBranchEnabled) { DelayBranchEnabled = delayBranchEnabled; Stall_IFace = CreateInputface <bool>(); LMemRdata_IFace = CreateInputface <ushort>(); HMemRdata_IFace = CreateInputface <ushort>(); BranchRequestFromCS_IFace = CreateInputface <bool>(); BranchPCRelModeFromCS_IFace = CreateInputface <bool>(); BranchPCFromCS_IFace = CreateInputface <uint>(); PCOut_OFace = CreateSyncOutputface <uint>(0); Instruction_OFace = CreateSyncOutputface <uint>(0); ValidCS_OFace = CreateSyncOutputface <bool>(false); Branched_OFace = CreateSyncOutputface <bool>(false); LMemEn_OFace = CreateAsyncOutputface <bool>(); LMemAddr_OFace = CreateAsyncOutputface <uint>(); HMemEn_OFace = CreateAsyncOutputface <bool>(); HMemAddr_OFace = CreateAsyncOutputface <uint>(); LMemEn_OFace.SetFunc(() => { return(!Stall_IFace); }); LMemAddr_OFace.SetFunc(() => { bool isPCRelMemInstruction = TestBit(Instruction_OFace.Value, 31) && TestBit(Instruction_OFace.Value, 24) && TestBit(Instruction_OFace.Value, 22); bool isJumpableInstruction = !TestBit(Instruction_OFace.Value, 31) && TestBit(Instruction_OFace.Value, 29); uint res = PCOut_OFace.Value >> 1; if (Branched_OFace.Value) { res += 0; } else if (isPCRelMemInstruction && TestBit(PCOut_OFace.Value, 0)) { res += 2; } else if (isPCRelMemInstruction || (isJumpableInstruction && TestBit(PCOut_OFace.Value, 0))) { res += 1; } return(res); }); HMemEn_OFace.SetFunc(() => { return(!Stall_IFace); }); HMemAddr_OFace.SetFunc(() => { bool isPCRelMemInstruction = TestBit(Instruction_OFace.Value, 31) && TestBit(Instruction_OFace.Value, 24) && TestBit(Instruction_OFace.Value, 22); bool isJumpableInstruction = !TestBit(Instruction_OFace.Value, 31) && TestBit(Instruction_OFace.Value, 29); uint res = PCOut_OFace.Value >> 1; if (Branched_OFace.Value) { if (TestBit(PCOut_OFace.Value, 0)) { res += 1; } else { res += 0; } } else if (isPCRelMemInstruction && TestBit(PCOut_OFace.Value, 0)) { res += 2; } else if (isPCRelMemInstruction || isJumpableInstruction || TestBit(PCOut_OFace.Value, 0)) { res += 1; } return(res); }); }
public ComputeStage() { PC_IFace = CreateInputface <uint>(); Stall_IFace = CreateInputface <bool>(); Instruction_IFace = CreateInputface <uint>(); ValidCS_IFace = CreateInputface <bool>(); RegWen_IFace = CreateInputface <bool>(); RegWdata_IFace = CreateInputface <uint>(); RegWno_IFace = CreateInputface <byte>(); MemOp_OFace = CreateSyncOutputface <bool>(false); MemRw_OFace = CreateSyncOutputface <bool>(false); AluRes_OFace = CreateSyncOutputface <uint>(0); RegRdataC_OFace = CreateSyncOutputface <uint>(0); RegNoC_OFace = CreateSyncOutputface <byte>(0); ValidAS_OFace = CreateSyncOutputface <bool>(false); BranchRequest_OFace = CreateAsyncOutputface <bool>(); BranchPCRelMode_OFace = CreateAsyncOutputface <bool>(); BranchPC_OFace = CreateAsyncOutputface <uint>(); RegisterFile = new SubRISC.RegisterFile(); reg_read0_OFace = CreateAsyncOutputface <RegisterFile.ReadCommand>(); reg_read1_OFace = CreateAsyncOutputface <RegisterFile.ReadCommand>(); reg_write0_OFace = CreateAsyncOutputface <RegisterFile.WriteCommand>(); reg_read0_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; RegisterFile.ReadCommand res = new RegisterFile.ReadCommand(); res.No = instrIsMemoryOperation ? instrOperandD : instrOperandA; res.Enabled = instrIsMemoryOperation ? instrMemoryOperationRW : ((res.No & 12) != 0); return(res); }); reg_read1_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; RegisterFile.ReadCommand res = new RegisterFile.ReadCommand(); res.No = (byte)(instrOperandB & 15); res.Enabled = !TestBit(instrOperandB, 4); return(res); }); reg_write0_OFace.SetFunc(() => { RegisterFile.WriteCommand res = new RegisterFile.WriteCommand(); res.No = RegWno_IFace; res.Enabled = RegWen_IFace; res.Value = RegWdata_IFace; return(res); }); RegisterFile.Read0_IFace.BindSource(reg_read0_OFace); RegisterFile.Read1_IFace.BindSource(reg_read1_OFace); RegisterFile.Write_IFace.BindSource(reg_write0_OFace); this.RegisterSubModule(RegisterFile); Alu = new SubRISC.Alu(); alu_a_OFace = CreateAsyncOutputface <uint>(); alu_b_OFace = CreateAsyncOutputface <uint>(); alu_opflag_OFace = CreateAsyncOutputface <bool>(); alu_condflag_OFace = CreateAsyncOutputface <byte>(); alu_a_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; if (instrIsMemoryOperation) { return((uint)(TestBit((uint)instrOperandA, 3) ? 0xFFFFFFF0 : 0u) | (uint)((instrOperandA & 7) << 1)); } else if (reg_read0_OFace.Value.Enabled) { return(RegisterFile.Read0_OFace.Value); } else if ((instrOperandA & 3) == 0) { return(0); } else if ((instrOperandA & 3) == 1) { return(0xFFFFFFFF); } else if ((instrOperandA & 3) == 2) { return(1); } else { return(0xFFFFFFFC); } }); alu_b_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; if (reg_read1_OFace.Value.Enabled) { return(RegisterFile.Read1_OFace.Value); } else if (TestBit(instrOperandB, 0)) { return(0xFFFFFFFF); } else if (TestBit(instrOperandB, 1)) { return(1); } else if (TestBit(instrOperandB, 2)) { return(PC_IFace << 1); } else if (TestBit(instrOperandB, 3)) { return(32); } else { return(0); } }); alu_opflag_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; return(TestBit(instrOpcode, 0)); }); alu_condflag_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; return(instrJumpCondition); }); Alu.OperandA_IFace.BindSource(alu_a_OFace); Alu.OperandB_IFace.BindSource(alu_b_OFace); Alu.OpFlag_IFace.BindSource(alu_opflag_OFace); Alu.CondFlag_IFace.BindSource(alu_condflag_OFace); this.RegisterSubModule(Alu); BranchRequest_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; return(ValidCS_IFace && !TestBit(Instruction_IFace, 31) && instrJumpFlag && Alu.CondResult_OFace.Value); }); BranchPCRelMode_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; return(true); }); BranchPC_OFace.SetFunc(() => { byte instrOpcode = (byte)((Instruction_IFace >> 30) & 3); bool instrJumpFlag = TestBit(Instruction_IFace, 29); byte instrOperandA = (byte)((Instruction_IFace >> 25) & 15); byte instrOperandB = (byte)((Instruction_IFace >> 20) & 31); byte instrOperandD = (byte)((Instruction_IFace >> 16) & 15); bool instrJumpByRegister = TestBit(Instruction_IFace, 15); byte instrJumpCondition = (byte)((Instruction_IFace >> 12) & 7); uint instrJumpAddress = (uint)((Instruction_IFace >> 0) & 0x7FF); bool instrIsMemoryOperation = TestBit(instrOpcode, 1) && !TestBit(instrOpcode, 0); bool instrMemoryOperationRW = instrJumpFlag; return((TestBit(Instruction_IFace, 11) ? 0xFFFFF800 : 0u) | (instrJumpAddress & 0x7FF)); }); }
public Subneg4XCircuitGroup(RAM ram, uint startupAddr) { Memory = ram; SyncMemory = new SyncRAMInterfaceRW1R1(this.Memory); RegisterSubModule(SyncMemory); Alu = new Subneg4X.Alu(); RegisterSubModule(Alu); { SyncMemoryRead1 = CreateAsyncOutputface <SyncRAMInterfaceRW1R1.ReadCommand>(); SyncMemoryRead2 = CreateAsyncOutputface <SyncRAMInterfaceRW1R1.ReadCommand>(); SyncMemoryWrite = CreateAsyncOutputface <SyncRAMInterfaceRW1R1.WriteCommand>(); MemOpA = CreateSyncOutputface <uint>(); MemOpB = CreateSyncOutputface <uint>(); MemOpAInput = CreateAsyncOutputface <uint>(); MemOpBInput = CreateAsyncOutputface <uint>(); State = CreateSyncOutputface <int>(-1); StateInput = CreateAsyncOutputface <int>(); ProgramCounter = CreateSyncOutputface <uint>(startupAddr); ProgramCounterInput = CreateAsyncOutputface <uint>(); SyncMemoryRead1.SetFunc(() => { switch (State.Value) { case -1: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = this.ProgramCounter.Value + 0, AccessType = EnumMemorymAccessType.Instruction }); case 0: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = this.SyncMemory.ReadValue1_OFace.Value, AccessType = EnumMemorymAccessType.Data }); case 1: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = this.ProgramCounter.Value + 2, AccessType = EnumMemorymAccessType.Instruction }); case 2: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = false //Writing to operand C }); case 3: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = (Alu.BranchCond_OFace.Value) ? (SyncMemory.ReadValue2_OFace.Value & 0x7FFFFFFF) : ProgramCounter.Value + 4, AccessType = EnumMemorymAccessType.Instruction }); case 4: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = false }); } throw new Exception(); }); SyncMemoryRead2.SetFunc(() => { switch (State.Value) { case -1: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = this.ProgramCounter.Value + 1, AccessType = EnumMemorymAccessType.Instruction }); case 0: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = this.SyncMemory.ReadValue2_OFace.Value, AccessType = EnumMemorymAccessType.Data }); case 1: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = this.ProgramCounter.Value + 3, AccessType = EnumMemorymAccessType.Instruction }); case 2: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = false, Address = this.ProgramCounter.Value + 3 }); case 3: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = true, Address = (Alu.BranchCond_OFace.Value) ? ((SyncMemory.ReadValue2_OFace.Value & 0x7FFFFFFF) + 1) : ProgramCounter.Value + 4 + 1, AccessType = EnumMemorymAccessType.Instruction }); case 4: return(new SyncRAMInterfaceRW1R1.ReadCommand() { Enabled = false }); } throw new Exception(); }); SyncMemoryWrite.SetFunc(() => { switch (State.Value) { case 2: return(new SyncRAMInterfaceRW1R1.WriteCommand() { Enabled = true, Address = this.SyncMemory.ReadValue1_OFace.Value, Value = Alu.AluResult_OFace.Value }); } return(new SyncRAMInterfaceRW1R1.WriteCommand() { Enabled = false }); }); SyncMemory.ReadCmd1_IFace.BindSource(this.SyncMemoryRead1); SyncMemory.ReadCmd2_IFace.BindSource(this.SyncMemoryRead2); SyncMemory.WriteCmd_IFace.BindSource(this.SyncMemoryWrite); MemOpAInput.SetFunc(() => { return((State.Value == 1) ? SyncMemory.ReadValue1_OFace.Value : MemOpA.Value); }); MemOpBInput.SetFunc(() => { return((State.Value == 1) ? SyncMemory.ReadValue2_OFace.Value : MemOpB.Value); }); MemOpA.AutoAssign(MemOpAInput); MemOpB.AutoAssign(MemOpBInput); Alu.OperandA_IFace.BindSource(MemOpA); Alu.OperandB_IFace.BindSource(MemOpB); Alu.OperandD_IFace.BindSource(SyncMemory.ReadValue2_OFace); StateInput.SetFunc(() => { switch (State.Value) { case -1: return(0); case 0: return(1); case 1: return(2); case 2: return(3); case 3: return(0); case 4: return(4); } return(-1); }); State.AutoAssign(StateInput); ProgramCounterInput.SetFunc(() => { if (State.Value == 3) { if (Alu.BranchCond_OFace.Value) { return(SyncMemory.ReadValue2_OFace.Value & 0x7FFFFFFF); } else { return(ProgramCounter.Value + 4); } } return(ProgramCounter.Value); }); ProgramCounter.AutoAssign(ProgramCounterInput); } }