Initial commit
This commit is contained in:
		
							
								
								
									
										24
									
								
								Libs/NanoBlaze/hdl/aluBOpSelector_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Libs/NanoBlaze/hdl/aluBOpSelector_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| ARCHITECTURE RTL OF aluBOpSelector IS | ||||
| BEGIN | ||||
|  | ||||
|   selectDataSource: process( | ||||
|     registerFileSel, registerFileIn, | ||||
|     scratchpadSel,   spadIn, | ||||
|     portInSel,       portIn, | ||||
|     instrDataSel,    instrData | ||||
|   ) | ||||
|   begin | ||||
|     if registerFileSel = '1' then | ||||
|       opB <= registerFileIn; | ||||
|     elsif scratchpadSel = '1' then | ||||
|       opB <= spadIn; | ||||
|     elsif portInSel = '1' then | ||||
|       opB <= portIn; | ||||
|     elsif instrDataSel = '1' then | ||||
|       opB <= instrData; | ||||
|     else | ||||
|       opB <= (others => '-'); | ||||
|     end if; | ||||
|   end process selectDataSource; | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
							
								
								
									
										113
									
								
								Libs/NanoBlaze/hdl/alu_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								Libs/NanoBlaze/hdl/alu_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,113 @@ | ||||
| ARCHITECTURE RTL OF alu IS | ||||
|  | ||||
|   signal aluCodeInt: unsigned(aluCode'range); | ||||
|   signal aArith: signed(opA'high+1 downto 0); | ||||
|   signal bArith: signed(opA'high+1 downto 0); | ||||
|   signal cInArith: signed(1 downto 0); | ||||
|   signal cInShift: std_ulogic; | ||||
|   signal yArith: signed(aluOut'high+1 downto 0); | ||||
|   signal aluOutInt: signed(aluOut'range); | ||||
|  | ||||
| BEGIN | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                       -- clear aluCode don't care LSB for shifts | ||||
|   aluCodeInt(aluCode'high downto 1) <= unsigned(aluCode(aluCode'high downto 1)); | ||||
|  | ||||
|   cleanupLsb: process(aluCode) | ||||
|   begin | ||||
|     if aluCode(aluCode'high) = '1' then | ||||
|       aluCodeInt(0) <= '0'; | ||||
|     else | ||||
|       aluCodeInt(0) <= aluCode(0); | ||||
|     end if; | ||||
|   end process cleanupLsb; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                              -- values for arithmetic operations | ||||
|   aArith <= signed(resize(unsigned(opA), aArith'length)); | ||||
|   bArith <= signed(resize(unsigned(opB), bArith'length)); | ||||
|   cInArith <= (0 => cIn, others => '0'); | ||||
|  | ||||
|   process(aluCode, cIn, opA) | ||||
|   begin | ||||
|     case aluCode(2 downto 1) is | ||||
|       when "00"   => cInShift <= cIn; | ||||
|       when "01"   => cInShift <= opA(opA'high); | ||||
|       when "10"   => cInShift <= opA(opA'low); | ||||
|       when "11"   => cInShift <= aluCode(0); | ||||
|       when others => cInShift <= '-'; | ||||
|     end case; | ||||
|   end process; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                -- alu operations | ||||
|   aluOperation: process( | ||||
|     aluCodeInt, | ||||
|     opA, opB, | ||||
|     aArith, bArith, cInArith, | ||||
|     cInShift, | ||||
|     yArith, aluOutInt | ||||
|   ) | ||||
|     variable xorAcc: std_ulogic; | ||||
|   begin | ||||
|     yArith <= (others => '-'); | ||||
|     cOut   <= '-'; | ||||
|     aluOutInt <= (others => '-'); | ||||
|     case to_integer(aluCodeInt) is | ||||
|       when  0 =>                                        -- LOAD sX, kk | ||||
|         aluOutInt <= opB; | ||||
|       when  2 =>                                        -- INPUT sX, pp | ||||
|         aluOutInt <= opB; | ||||
|       when  3 =>                                        -- FETCH sX, ss | ||||
|         aluOutInt <= opB; | ||||
|       when  5 =>                                        -- AND sX, kk | ||||
|         aluOutInt <= opA and opB; | ||||
|         cOut      <= '0'; | ||||
|       when  6 =>                                        -- OR sX, kk | ||||
|         aluOutInt <= opA or opB; | ||||
|         cOut      <= '0'; | ||||
|       when  7 =>                                        -- XOR sX, kk | ||||
|         aluOutInt <= opA xor opB; | ||||
|         cOut      <= '0'; | ||||
|       when  9 =>                                        -- TEST sX, kk | ||||
|         aluOutInt <= opA and opB; | ||||
|         xorAcc := '0'; | ||||
|         for index in aluOutInt'range loop | ||||
|           xorAcc := xorAcc xor aluOutInt(index); | ||||
|         end loop; | ||||
|         cOut      <= xorAcc; | ||||
|       when 10 =>                                        -- COMPARE sX, kk | ||||
|         yArith    <= aArith - bArith; | ||||
|         aluOutInt <= yArith(aluOut'range); | ||||
|         cOut      <= yArith(yArith'high); | ||||
|       when 12 =>                                        -- ADD sX, kk | ||||
|         yArith    <= aArith + bArith; | ||||
|         aluOutInt <= yArith(aluOut'range); | ||||
|         cOut      <= yArith(yArith'high); | ||||
|       when 13 =>                                        -- ADDCY sX, kk | ||||
|         yArith    <= (aArith + bArith) + cInArith; | ||||
|         aluOutInt <= yArith(aluOut'range); | ||||
|         cOut      <= yArith(yArith'high); | ||||
|       when 14 =>                                        -- SUB sX, kk | ||||
|         yArith    <= aArith - bArith; | ||||
|         aluOutInt <= yArith(aluOut'range); | ||||
|         cOut      <= yArith(yArith'high); | ||||
|       when 15 =>                                        -- SUBCY sX, kk | ||||
|         yArith    <= (aArith - bArith) - cInArith; | ||||
|         aluOutInt <= yArith(aluOut'range); | ||||
|         cOut      <= yArith(yArith'high); | ||||
|       when 16 to 23 =>                                  -- SL sX | ||||
|         aluOutInt <= opA(opA'high-1 downto 0) & cInShift; | ||||
|         cOut      <= opA(opA'high); | ||||
|       when 24 to 31 =>                                  -- SR sX | ||||
|         aluOutInt <= cInShift & opA(opA'high downto 1); | ||||
|         cOut      <= opA(0); | ||||
|       when others => | ||||
|         aluOutInt <= (others => '-'); | ||||
|     end case; | ||||
|   end process aluOperation; | ||||
|  | ||||
|   aluOut <= aluOutInt; | ||||
|   zero <= '1' when aluOutInt = 0 else '0'; | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
							
								
								
									
										40
									
								
								Libs/NanoBlaze/hdl/branchStack_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								Libs/NanoBlaze/hdl/branchStack_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| ARCHITECTURE RTL OF branchStack IS | ||||
|  | ||||
|   subtype progCounterType is unsigned(progCounter'range); | ||||
|   type progCounterArrayType is array (0 to 2**stackPointerBitNb) of progCounterType; | ||||
|   signal progCounterArray : progCounterArrayType; | ||||
|  | ||||
|   signal writePointer : unsigned(stackPointerBitNb-1 downto 0); | ||||
|   signal readPointer  : unsigned(stackPointerBitNb-1 downto 0); | ||||
|  | ||||
| BEGIN | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                -- stack pointers | ||||
|   updateStackPointer: process(reset, clock) | ||||
|   begin | ||||
|     if reset = '1' then | ||||
|       writePointer <= (others => '0'); | ||||
|     elsif rising_edge(clock) then | ||||
|       if storePC = '1' then | ||||
|         writePointer <= writePointer + 1; | ||||
|       elsif prevPC = '1' then | ||||
|         writePointer <= writePointer - 1; | ||||
|       end if; | ||||
|     end if; | ||||
|   end process updateStackPointer; | ||||
|  | ||||
|   readPointer <= writePointer - 1; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                        -- program counters stack | ||||
|   updateStack: process(reset, clock) | ||||
|   begin | ||||
|     if rising_edge(clock) then | ||||
|       if storePc = '1' then | ||||
|         progCounterArray(to_integer(writePointer)) <= progCounter; | ||||
|       end if; | ||||
|       storedProgCounter <= progCounterArray(to_integer(readPointer)); | ||||
|     end if; | ||||
|   end process updateStack; | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
							
								
								
									
										236
									
								
								Libs/NanoBlaze/hdl/controller_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								Libs/NanoBlaze/hdl/controller_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,236 @@ | ||||
| ARCHITECTURE RTL OF controller IS | ||||
|  | ||||
|   signal en1, enInt: std_ulogic; | ||||
|  | ||||
|   constant opCodeLength : integer := 5; | ||||
|   subtype opCodeType is std_ulogic_vector(opCodeLength-1 downto 0); | ||||
|   constant opLoad  : opCodeType := "00000"; | ||||
|   constant opInput : opCodeType := "00010"; | ||||
|   constant opFetch : opCodeType := "00011"; | ||||
|   constant opAnd   : opCodeType := "00101"; | ||||
|   constant opOr    : opCodeType := "00110"; | ||||
|   constant opXor   : opCodeType := "00111"; | ||||
|   constant opTest  : opCodeType := "01001"; | ||||
|   constant opComp  : opCodeType := "01010"; | ||||
|   constant opAdd   : opCodeType := "01100"; | ||||
|   constant opAddCy : opCodeType := "01101"; | ||||
|   constant opSub   : opCodeType := "01110"; | ||||
|   constant opSubCy : opCodeType := "01111"; | ||||
|   constant opShRot : opCodeType := "10000"; | ||||
|   constant opRet   : opCodeType := "10101"; | ||||
|   constant opOutput: opCodeType := "10110"; | ||||
|   constant opStore : opCodeType := "10111"; | ||||
|   constant opCall  : opCodeType := "11000"; | ||||
|   constant opJump  : opCodeType := "11010"; | ||||
|   constant opIntF  : opCodeType := "11110"; | ||||
|  | ||||
|   constant branchConditionLength : integer := 3; | ||||
|   subtype branchConditionType is std_ulogic_vector(branchConditionLength-1 downto 0); | ||||
|   constant brAw  : branchConditionType := "000"; | ||||
|   constant brZ   : branchConditionType := "100"; | ||||
|   constant brNZ  : branchConditionType := "101"; | ||||
|   constant brC   : branchConditionType := "110"; | ||||
|   constant brNC  : branchConditionType := "111"; | ||||
|  | ||||
|   signal aluOpSel: std_ulogic; | ||||
|   signal regWriteEn: std_ulogic; | ||||
|  | ||||
|   signal flagsEn, flagsEnable: std_ulogic; | ||||
|   signal carrySaved: std_ulogic; | ||||
|   signal zeroSaved: std_ulogic; | ||||
|  | ||||
|   signal branchEnable1, branchEnable: std_ulogic; | ||||
|   signal discardOpCode: std_ulogic; | ||||
|  | ||||
|   signal updateIntFlag: std_ulogic; | ||||
|  | ||||
| BEGIN | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                 -- Enable signal | ||||
|   buildEnable: process(reset, clock) | ||||
|   begin | ||||
|     if reset = '1' then | ||||
|       en1 <= '0'; | ||||
|     elsif rising_edge(clock) then | ||||
|       en1 <= '1'; | ||||
|     end if; | ||||
|   end process buildEnable; | ||||
|  | ||||
|   enInt <= en1 and en;  -- don't enable very first instruction twice | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                  -- ALU controls | ||||
|   selectdataSource: process(opCode) | ||||
|   begin | ||||
|     aluOpSel      <= '0'; | ||||
|     portInSel     <= '0'; | ||||
|     scratchpadSel <= '0'; | ||||
|     case opCode(opCodeLength-1 downto 0) is | ||||
|       when opLoad  => aluOpSel      <= '1'; | ||||
|       when opInput => portInSel     <= '1'; | ||||
|       when opFetch => scratchpadSel <= '1'; | ||||
|       when opAnd   => aluOpSel      <= '1'; | ||||
|       when opOr    => aluOpSel      <= '1'; | ||||
|       when opXor   => aluOpSel      <= '1'; | ||||
|       when opTest  => aluOpSel      <= '1'; | ||||
|       when opComp  => aluOpSel      <= '1'; | ||||
|       when opAdd   => aluOpSel      <= '1'; | ||||
|       when opAddCy => aluOpSel      <= '1'; | ||||
|       when opSub   => aluOpSel      <= '1'; | ||||
|       when opSubCy => aluOpSel      <= '1'; | ||||
|       when opShRot => aluOpSel      <= '1'; | ||||
|       when others  => aluOpSel      <= '-'; | ||||
|                       portInSel     <= '-'; | ||||
|                       scratchpadSel <= '-'; | ||||
|     end case; | ||||
|   end process selectdataSource; | ||||
|  | ||||
|   registerFileSel <= aluOpSel and      twoRegInstr; | ||||
|   instrDataSel    <= aluOpSel and (not twoRegInstr); | ||||
|  | ||||
|   regWriteEn <= enInt and (not discardOpCode); | ||||
|  | ||||
|   regWriteTable: process(opCode, regWriteEn) | ||||
|   begin | ||||
|     case opCode(opCodeLength-1 downto 0) is | ||||
|       when opLoad  => regWrite <= regWriteEn; | ||||
|       when opInput => regWrite <= regWriteEn; | ||||
|       when opFetch => regWrite <= regWriteEn; | ||||
|       when opAnd   => regWrite <= regWriteEn; | ||||
|       when opOr    => regWrite <= regWriteEn; | ||||
|       when opXor   => regWrite <= regWriteEn; | ||||
|       when opAdd   => regWrite <= regWriteEn; | ||||
|       when opAddCy => regWrite <= regWriteEn; | ||||
|       when opSub   => regWrite <= regWriteEn; | ||||
|       when opSubCy => regWrite <= regWriteEn; | ||||
|       when opShRot => regWrite <= regWriteEn; | ||||
|       when others  => regWrite <= '0'; | ||||
|     end case; | ||||
|   end process regWriteTable; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                  -- I/O controls | ||||
|   readStrobe  <= enInt when (opCode = opInput) and (discardOpCode = '0') | ||||
|     else '0'; | ||||
|   writeStrobe <= enInt when (opCode = opOutput) and (discardOpCode = '0') | ||||
|     else '0'; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                           -- scratchpad controls | ||||
|   scratchpadWrite <= '1' when opCode = opStore else '0'; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                   -- Carry logic | ||||
|   flagsEn <= enInt and (not branchEnable); | ||||
|  | ||||
|   flagsEnableTable: process(opCode, flagsEn) | ||||
|   begin | ||||
|     case opCode(opCodeLength-1 downto 0) is | ||||
|       when opAnd   => flagsEnable <= flagsEn; | ||||
|       when opOr    => flagsEnable <= flagsEn; | ||||
|       when opXor   => flagsEnable <= flagsEn; | ||||
|       when opTest  => flagsEnable <= flagsEn; | ||||
|       when opComp  => flagsEnable <= flagsEn; | ||||
|       when opAdd   => flagsEnable <= flagsEn; | ||||
|       when opAddCy => flagsEnable <= flagsEn; | ||||
|       when opSub   => flagsEnable <= flagsEn; | ||||
|       when opSubCy => flagsEnable <= flagsEn; | ||||
|       when opShRot => flagsEnable <= flagsEn; | ||||
|       when others  => flagsEnable <= '0'; | ||||
|     end case; | ||||
|   end process flagsEnableTable; | ||||
|  | ||||
|   saveCarries: process(reset, clock) | ||||
|   begin | ||||
|     if reset = '1' then | ||||
|       carrySaved <= '0'; | ||||
|       zeroSaved <= '0'; | ||||
|     elsif rising_edge(clock) then | ||||
|       if flagsEnable = '1' then | ||||
|         carrySaved <= cOut; | ||||
|         zeroSaved <= zero; | ||||
|       end if; | ||||
|     end if; | ||||
|   end process saveCarries; | ||||
|  | ||||
|   cIn <= carrySaved; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                      -- Program counter controls | ||||
|   checkBranchCondition: process(branchCond, zeroSaved, carrySaved) | ||||
|   begin | ||||
|     case branchCond(branchConditionLength-1 downto 0) is | ||||
|       when brAw => branchEnable1 <= '1'; | ||||
|       when brZ  => branchEnable1 <= zeroSaved; | ||||
|       when brNZ => branchEnable1 <= not zeroSaved; | ||||
|       when brC  => branchEnable1 <= carrySaved; | ||||
|       when brNC => branchEnable1 <= not carrySaved; | ||||
|       when others => branchEnable1 <= '-'; | ||||
|     end case; | ||||
|   end process checkBranchCondition; | ||||
|  | ||||
|   branchEnableTable: process(opCode, branchEnable1, discardOpCode) | ||||
|   begin | ||||
|     if discardOpCode = '0' then | ||||
|       case opCode(opCodeLength-1 downto 0) is | ||||
|         when opRet  => branchEnable <= branchEnable1; | ||||
|         when opCall => branchEnable <= branchEnable1; | ||||
|         when opJump => branchEnable <= branchEnable1; | ||||
|         when others  => branchEnable <= '0'; | ||||
|       end case; | ||||
|     else | ||||
|       branchEnable <= '0'; | ||||
|     end if; | ||||
|   end process branchEnableTable; | ||||
|  | ||||
|   progCounterControlTable: process(opCode, enInt, branchEnable) | ||||
|   begin | ||||
|     incPC <= enInt; | ||||
|     loadInstrAddress <= '0'; | ||||
|     loadStoredPC     <= '0'; | ||||
|     case opCode(opCodeLength-1 downto 0) is | ||||
|       when opRet  => incPC <= not branchEnable; | ||||
|                      loadStoredPC <= enInt and branchEnable; | ||||
|       when opCall => incPC <= not branchEnable; | ||||
|                      loadInstrAddress <= enInt and branchEnable; | ||||
|       when opJump => incPC <= not branchEnable; | ||||
|                      loadInstrAddress <= enInt and branchEnable; | ||||
|       when others => null; | ||||
|     end case; | ||||
|   end process progCounterControlTable; | ||||
|  | ||||
|   -- If a branch condition is met, the next operation has to be discarded. | ||||
|   -- This is due to the synchronous operation of the program ROM: the | ||||
|   -- instructions are provided one clock period after the program counter. | ||||
|   -- so while the branch operation is processed, the next instruction is | ||||
|   -- already being fetched. | ||||
|   delayBranchEnable: process(reset, clock) | ||||
|   begin | ||||
|     if reset = '1' then | ||||
|       discardOpCode <= '0'; | ||||
|     elsif rising_edge(clock) then | ||||
|       discardOpCode <= branchEnable; | ||||
|     end if; | ||||
|   end process delayBranchEnable; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                        -- Stack pointer controls | ||||
|   pcStackControlTable: process(discardOpCode, opCode, enInt) | ||||
|   begin | ||||
|     storePC <= '0'; | ||||
|     prevPC  <= '0'; | ||||
|     if discardOpCode = '0' then | ||||
|       case opCode(opCodeLength-1 downto 0) is | ||||
|         when opRet  => prevPC <= enInt; | ||||
|         when opCall => storePC <= enInt; | ||||
|         when others  => null; | ||||
|       end case; | ||||
|     end if; | ||||
|   end process pcStackControlTable; | ||||
|  | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                             -- interrupt control | ||||
|   updateIntFlag <= '1' when opCode = opIntF else '0'; | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
							
								
								
									
										56
									
								
								Libs/NanoBlaze/hdl/instructionDecoder_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								Libs/NanoBlaze/hdl/instructionDecoder_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| ARCHITECTURE RTL OF instructionDecoder IS | ||||
|  | ||||
|   constant opCodeIndexH         : integer := instruction'high; | ||||
|   constant opCodeIndexL         : integer := opCodeIndexH - opCodeBitNb + 1; | ||||
|  | ||||
|   constant twoRegInstrIndex     : integer := opCodeIndexL - 1; | ||||
|   constant ioAddrIndexed        : integer := twoRegInstrIndex; | ||||
|  | ||||
|   constant addrAIndexH          : integer := twoRegInstrIndex - 1; | ||||
|   constant addrAIndexL          : integer := addrAIndexH - registerAddressBitNb + 1; | ||||
|  | ||||
|   constant immediateDataIndexH  : integer := registerBitNb-1; | ||||
|   constant immediateDataIndexL  : integer := 0; | ||||
|   constant addrBIndexH          : integer := addrAIndexL - 1; | ||||
|   constant addrBIndexL          : integer := addrBIndexH - registerAddressBitNb + 1; | ||||
|  | ||||
|   constant aluCodeIndexH        : integer := opCodeIndexH; | ||||
|   constant aluCodeIndexL        : integer := aluCodeIndexH - aluCodeBitNb + 1; | ||||
|  | ||||
|   constant portAddressH         : integer := registerBitNb-1; | ||||
|   constant portAddressL         : integer := portAddressH-portAddressBitNb+1; | ||||
|   constant spadAddressH         : integer := registerBitNb-1; | ||||
|   constant spadAddressL         : integer := spadAddressH-spadAddressBitNb+1; | ||||
|  | ||||
|   constant branchCondH          : integer := opCodeIndexL-1; | ||||
|   constant branchCondL          : integer := branchCondH-branchCondBitNb+1; | ||||
|  | ||||
| BEGIN | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                   -- ALU control | ||||
|   aluCode <= | ||||
|     instruction(aluCodeIndexH downto aluCodeIndexL) | ||||
|       when instruction(aluCodeIndexH) = '0' else | ||||
|     '1' & instruction(aluCodeBitNb-2 downto 0); | ||||
|   opCode <= instruction(opCodeIndexH downto opCodeIndexL); | ||||
|   twoRegInstr <= instruction(twoRegInstrIndex); | ||||
|   addrA <= unsigned(instruction(addrAIndexH downto addrAIndexL)); | ||||
|   addrB <= unsigned(instruction(addrBIndexH downto addrBIndexL)); | ||||
|   instrData <= signed(instruction(immediateDataIndexH downto immediateDataIndexL)); | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                   -- I/O control | ||||
|   portIndexedSel <= instruction(ioAddrIndexed); | ||||
|   portAddress <= unsigned(instruction(portAddressH downto portAddressL)); | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                            -- scratchpad control | ||||
|   spadIndexedSel <= instruction(ioAddrIndexed); | ||||
|   spadAddress <= unsigned(instruction(spadAddressH downto spadAddressL)); | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                                -- branch control | ||||
|   branchCond <= instruction(branchCondH downto branchCondL); | ||||
|   instrAddress <= unsigned(instruction(instrAddress'range)); | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
							
								
								
									
										565
									
								
								Libs/NanoBlaze/hdl/nanoAsm.pl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										565
									
								
								Libs/NanoBlaze/hdl/nanoAsm.pl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,565 @@ | ||||
| #!/usr/bin/env perl | ||||
|  | ||||
| my $indent = ' ' x 2; | ||||
| my $separator = '-' x 80; | ||||
|  | ||||
| ################################################################################ | ||||
| # Input arguments | ||||
| # | ||||
| use Getopt::Std; | ||||
| my %opts; | ||||
| getopts('hva:d:r:kz', \%opts); | ||||
|  | ||||
| die("\n". | ||||
|     "Usage: $0 [options] fileSpec\n". | ||||
|     "\n". | ||||
|     "Options:\n". | ||||
|     "${indent}-h        display this help message\n". | ||||
|     "${indent}-v        verbose\n". | ||||
|     "${indent}-a bitNb  the number of program address bits\n". | ||||
|     "${indent}-d bitNb  the number of data bits\n". | ||||
|     "${indent}-r bitNb  the number of register address bits\n". | ||||
|     "${indent}-k        keep source comments in VHDL code\n". | ||||
|     "${indent}-z        zero don't care bits in VHDL ROM code\n". | ||||
|     "\n". | ||||
|     "Assemble code to VHDL for the nanoBlaze processor.\n". | ||||
|     "\n". | ||||
|     "More information with: perldoc $0\n". | ||||
|     "\n". | ||||
|     "" | ||||
|    ) if ($opts{h}); | ||||
|  | ||||
| my $verbose              = $opts{v}; | ||||
| my $keepComments         = $opts{k}; | ||||
| my $zeroDontCares        = $opts{z}; | ||||
| my $addressBitNb         = $opts{a} || 10; | ||||
| my $registerBitNb        = $opts{d} || 8; | ||||
| my $registerAddressBitNb = $opts{r} || 4; | ||||
|  | ||||
| my $asmFileSpec = $ARGV[0] || 'nanoTest.asm'; | ||||
| my $outFileSpec = $ARGV[1] || 'rom_mapped.vhd'; | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # System constants | ||||
| # | ||||
| my $binaryOpCodeLength = 6; | ||||
| my $binaryBranchLength = 5; | ||||
| my $binaryBranchConditionLength = 3; | ||||
|  | ||||
| my $opCodeBaseLength = 10; | ||||
| my $vhdlAddressLength = 14; | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Derived values | ||||
| # | ||||
|                                                                     # file specs | ||||
| my $baseFileSpec = $asmFileSpec; | ||||
| $baseFileSpec =~ s/\..*//i; | ||||
| my $asm1FileSpec = "$baseFileSpec.asm1";        # formatted assembly code | ||||
| my $asm2FileSpec = "$baseFileSpec.asm2";        # code with addresses replaced | ||||
| my $vhdlFileSpec = "$baseFileSpec.vhd"; | ||||
|                                                             # instruction length | ||||
| my $binaryOperationInstructionLength = | ||||
|   $binaryOpCodeLength + | ||||
|   $registerAddressBitNb + | ||||
|   $registerBitNb; | ||||
| my $binaryBranchInstructionLength = | ||||
|   $binaryBranchLength + | ||||
|   $binaryBranchConditionLength + | ||||
|   $addressBitNb; | ||||
| my $binaryInstructionLength = $binaryOperationInstructionLength; | ||||
| if ($binaryBranchInstructionLength > $binaryInstructionLength) { | ||||
|   $binaryInstructionLength = $binaryBranchInstructionLength | ||||
| } | ||||
|                                                       # assembler string lengths | ||||
| my $registerCharNb = int( ($registerBitNb-1)/4 ) + 1; | ||||
| my $addressCharNb = int( ($addressBitNb-1)/4 ) + 1; | ||||
|                                                            # vhdl string lengths | ||||
| my $vhdlOpCodeLength = $binaryOpCodeLength + 4; | ||||
| my $opCodeTotalLength = 22 + $registerCharNb; | ||||
| my $vhdlOperand1Length = $registerAddressBitNb + 3; | ||||
| my $vhdlOperand2Length = $registerBitNb + 4; | ||||
| if ($addressBitNb + 3 > $vhdlOperand2Length) { | ||||
|   $vhdlOperand2Length = $addressBitNb + 3 | ||||
| } | ||||
| my $vhdlTotalLength = $vhdlOpCodeLength; | ||||
| $vhdlTotalLength = $vhdlTotalLength + $vhdlOperand1Length + $vhdlOperand2Length; | ||||
| $vhdlTotalLength = $vhdlTotalLength + 2*2; # '& ' | ||||
| $vhdlTotalLength = $vhdlTotalLength + 1;   # ',' | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # System variables | ||||
| # | ||||
| my %constants = (); | ||||
| my %addresses = (); | ||||
|  | ||||
| ################################################################################ | ||||
| # Functions | ||||
| # | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Find constant from "CONSTANT" statement | ||||
| # | ||||
| sub findNewConstant { | ||||
|   my ($codeLine) = @_; | ||||
|  | ||||
|   $codeLine =~ s/CONSTANT\s+//; | ||||
|   my ($name, $value) = split(/,\s*/, $codeLine); | ||||
|   $value = hex($value); | ||||
|  | ||||
|   return ($name, $value); | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Find address from "ADDRESS" statement | ||||
| # | ||||
| sub findNewAddress { | ||||
|   my ($codeLine) = @_; | ||||
|  | ||||
|   $codeLine =~ s/ADDRESS\s*//; | ||||
|   my $address = hex($codeLine); | ||||
|  | ||||
|   return $address; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Format opcodes | ||||
| # | ||||
| sub prettyPrint { | ||||
|   my ($codeLine) = @_; | ||||
|  | ||||
|   my ($opcode, $arguments) = split(/ /, $codeLine, 2); | ||||
|   $opcode = $opcode . ' ' x ($opCodeBaseLength - length($opcode)); | ||||
|   $arguments =~ s/,*\s+/, /; | ||||
|   $codeLine = $opcode . $arguments; | ||||
|  | ||||
|   return $codeLine; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Format to binary | ||||
| # | ||||
| sub toBinary { | ||||
|   my ($operand, $bitNb) = @_; | ||||
|  | ||||
|   #$operand = sprintf("%0${bitNb}b", $operand); | ||||
|  | ||||
|   my $hexCharNb = int($bitNb/4) + 1; | ||||
|   $operand = sprintf("%0${hexCharNb}X", $operand); | ||||
|   $operand =~ s/0/0000/g; | ||||
|   $operand =~ s/1/0001/g; | ||||
|   $operand =~ s/2/0010/g; | ||||
|   $operand =~ s/3/0011/g; | ||||
|   $operand =~ s/4/0100/g; | ||||
|   $operand =~ s/5/0101/g; | ||||
|   $operand =~ s/6/0110/g; | ||||
|   $operand =~ s/7/0111/g; | ||||
|   $operand =~ s/8/1000/g; | ||||
|   $operand =~ s/9/1001/g; | ||||
|   $operand =~ s/A/1010/g; | ||||
|   $operand =~ s/B/1011/g; | ||||
|   $operand =~ s/C/1100/g; | ||||
|   $operand =~ s/D/1101/g; | ||||
|   $operand =~ s/E/1110/g; | ||||
|   $operand =~ s/F/1111/g; | ||||
|   $operand = substr($operand, length($operand)-$bitNb, $bitNb); | ||||
|  | ||||
|   return $operand; | ||||
| } | ||||
|  | ||||
| ################################################################################ | ||||
| # Program start | ||||
| # | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Display information | ||||
| # | ||||
| if ($verbose > 0) { | ||||
|   print "$separator\n"; | ||||
|   print "Assembling $asmFileSpec to $vhdlFileSpec\n"; | ||||
| } | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Calculate adresses, store address labels | ||||
| # | ||||
| if ($verbose > 0) { | ||||
|   print "${indent}Pass 1: from $asmFileSpec to $asm1FileSpec\n"; | ||||
| } | ||||
|  | ||||
| my $romAddress = 0; | ||||
| open(asmFile, "<$asmFileSpec") or die "Unable to open file, $!"; | ||||
| open(asm1File, ">$asm1FileSpec") or die "Unable to open file, $!"; | ||||
| while(my $line = <asmFile>) { | ||||
|   chomp($line); | ||||
|                                                         # split code and comment | ||||
|   my ($codeLine, $comment) = split(/;/, $line, 2); | ||||
|                                                           # handle address label | ||||
|   if ($codeLine =~ m/:/) { | ||||
|     (my $label, $codeLine) = split(/:/, $codeLine); | ||||
|     $label =~ s/\s*//; | ||||
|     print asm1File "; _${label}_:\n"; | ||||
|     $addresses{$label} = sprintf("%0${addressCharNb}X", $romAddress); | ||||
|   } | ||||
|                                                                   # cleanup code | ||||
|   $codeLine =~ s/\s+/ /g; | ||||
|   $codeLine =~ s/\A\s//; | ||||
|   $codeLine =~ s/\s\Z//; | ||||
|   $codeLine =~ s/\s,/,/; | ||||
|   if ($codeLine) { | ||||
|                                                     # handle ADDRESS declaration | ||||
|     if ($codeLine =~ m/ADDRESS/) { | ||||
|       $romAddress = findNewAddress($codeLine); | ||||
|     } | ||||
|                                                    # handle CONSTANT declaration | ||||
|     elsif ($codeLine =~ m/CONSTANT/) { | ||||
|       ($name, $value) = findNewConstant($codeLine); | ||||
|       $constants{$name} = sprintf("%0${registerCharNb}X", $value); | ||||
|     } | ||||
|                                                          # print cleaned-up code | ||||
|     else { | ||||
|       $codeLine = prettyPrint($codeLine); | ||||
|       print asm1File sprintf("%0${addressCharNb}X", $romAddress), ": $codeLine"; | ||||
|       if ($comment) { | ||||
|         print asm1File " ;$comment"; | ||||
|       } | ||||
|       print asm1File "\n"; | ||||
|       $romAddress = $romAddress + 1; | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
|     print asm1File ";$comment\n"; | ||||
|   } | ||||
| } | ||||
| close(asmFile); | ||||
| close(asm1File); | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Replace constant values and address labels | ||||
| # | ||||
| if ($verbose > 0) { | ||||
|   print "${indent}Pass 2: from $asm1FileSpec to $asm2FileSpec\n"; | ||||
| } | ||||
|  | ||||
| open(asm2File, ">$asm2FileSpec") or die "Unable to open file, $!"; | ||||
| open(asm1File, "<$asm1FileSpec") or die "Unable to open file, $!"; | ||||
| while(my $line = <asm1File>) { | ||||
|   chomp($line); | ||||
|                                                         # split code and comment | ||||
|   my ($opcode, $comment) = split(/;/, $line, 2); | ||||
|   if ( ($line =~ m/;/) and ($comment eq '') ) { | ||||
|     $comment = ' '; | ||||
|   } | ||||
|                                                                   # cleanup code | ||||
|   $opcode =~ s/\s+\Z//; | ||||
|                                                              # replace constants | ||||
|   foreach my $name (keys %constants) { | ||||
|     $opcode =~ s/$name/$constants{$name}/g; | ||||
|   } | ||||
|                                                              # replace addresses | ||||
|   foreach my $label (keys %addresses) { | ||||
|     $opcode =~ s/$label/$addresses{$label}/g; | ||||
|   } | ||||
|                                                                   # cleanup code | ||||
|   $opcode = uc($opcode); | ||||
|   $opcode =~ s/\sS([0-9A-F])/ s$1/g; | ||||
|                                                          # print cleaned-up code | ||||
|   if ($comment) { | ||||
|     if ($opcode) { | ||||
|       $opcode = $opcode . ' ' x ($opCodeTotalLength - length($opcode)); | ||||
|     } | ||||
|     $comment =~ s/\s+\Z//; | ||||
|     print asm2File "$opcode;$comment\n"; | ||||
|   } | ||||
|   else { | ||||
|     print asm2File "$opcode\n"; | ||||
|   } | ||||
| } | ||||
| close(asm1File); | ||||
| close(asm2File); | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Write VHDL ROM code | ||||
| # | ||||
| if ($verbose > 0) { | ||||
|   print "${indent}Pass 3: from $asm2FileSpec to $vhdlFileSpec\n"; | ||||
| } | ||||
| open(vhdlFile, ">$vhdlFileSpec") or die "Unable to open file, $!"; | ||||
| print vhdlFile <<DONE; | ||||
| ARCHITECTURE mapped OF programRom IS | ||||
|  | ||||
|   subtype opCodeType is std_ulogic_vector(5 downto 0); | ||||
|   constant opLoadC   : opCodeType := "000000"; | ||||
|   constant opLoadR   : opCodeType := "000001"; | ||||
|   constant opInputC  : opCodeType := "000100"; | ||||
|   constant opInputR  : opCodeType := "000101"; | ||||
|   constant opFetchC  : opCodeType := "000110"; | ||||
|   constant opFetchR  : opCodeType := "000111"; | ||||
|   constant opAndC    : opCodeType := "001010"; | ||||
|   constant opAndR    : opCodeType := "001011"; | ||||
|   constant opOrC     : opCodeType := "001100"; | ||||
|   constant opOrR     : opCodeType := "001101"; | ||||
|   constant opXorC    : opCodeType := "001110"; | ||||
|   constant opXorR    : opCodeType := "001111"; | ||||
|   constant opTestC   : opCodeType := "010010"; | ||||
|   constant opTestR   : opCodeType := "010011"; | ||||
|   constant opCompC   : opCodeType := "010100"; | ||||
|   constant opCompR   : opCodeType := "010101"; | ||||
|   constant opAddC    : opCodeType := "011000"; | ||||
|   constant opAddR    : opCodeType := "011001"; | ||||
|   constant opAddCyC  : opCodeType := "011010"; | ||||
|   constant opAddCyR  : opCodeType := "011011"; | ||||
|   constant opSubC    : opCodeType := "011100"; | ||||
|   constant opSubR    : opCodeType := "011101"; | ||||
|   constant opSubCyC  : opCodeType := "011110"; | ||||
|   constant opSubCyR  : opCodeType := "011111"; | ||||
|   constant opShRot   : opCodeType := "100000"; | ||||
|   constant opOutputC : opCodeType := "101100"; | ||||
|   constant opOutputR : opCodeType := "101101"; | ||||
|   constant opStoreC  : opCodeType := "101110"; | ||||
|   constant opStoreR  : opCodeType := "101111"; | ||||
|  | ||||
|   subtype shRotCinType is std_ulogic_vector(2 downto 0); | ||||
|   constant shRotLdC : shRotCinType := "00-"; | ||||
|   constant shRotLdM : shRotCinType := "01-"; | ||||
|   constant shRotLdL : shRotCinType := "10-"; | ||||
|   constant shRotLd0 : shRotCinType := "110"; | ||||
|   constant shRotLd1 : shRotCinType := "111"; | ||||
|  | ||||
|   constant registerAddressBitNb : positive := $registerAddressBitNb; | ||||
|   constant shRotPadLength : positive | ||||
|     := dataOut'length - opCodeType'length - registerAddressBitNb | ||||
|      - 1 - shRotCinType'length; | ||||
|   subtype shRotDirType is std_ulogic_vector(1+shRotPadLength-1 downto 0); | ||||
|   constant shRotL : shRotDirType := (0 => '0', others => '-'); | ||||
|   constant shRotR : shRotDirType := (0 => '1', others => '-'); | ||||
|  | ||||
|   subtype branchCodeType is std_ulogic_vector(4 downto 0); | ||||
|   constant brRet  : branchCodeType := "10101"; | ||||
|   constant brCall : branchCodeType := "11000"; | ||||
|   constant brJump : branchCodeType := "11010"; | ||||
|   constant brReti : branchCodeType := "11100"; | ||||
|   constant brEni  : branchCodeType := "11110"; | ||||
|  | ||||
|   subtype branchConditionType is std_ulogic_vector(2 downto 0); | ||||
|   constant brDo : branchConditionType := "000"; | ||||
|   constant brZ  : branchConditionType := "100"; | ||||
|   constant brNZ : branchConditionType := "101"; | ||||
|   constant brC  : branchConditionType := "110"; | ||||
|   constant brNC : branchConditionType := "111"; | ||||
|  | ||||
|   subtype memoryWordType is std_ulogic_vector(dataOut'range); | ||||
|   type memoryArrayType is array (0 to 2**address'length-1) of memoryWordType; | ||||
|  | ||||
|   signal memoryArray : memoryArrayType := ( | ||||
| DONE | ||||
| open(asm2File, "<$asm2FileSpec") or die "Unable to open file, $!"; | ||||
| while(my $line = <asm2File>) { | ||||
|   chomp($line); | ||||
|                                                         # split code and comment | ||||
|   my ($opcode, $comment) = split(/;/, $line, 2); | ||||
|   if ( ($line =~ m/;/) and ($comment eq '') ) { | ||||
|     $comment = ' '; | ||||
|   } | ||||
|                                                              # addresses to VHDL | ||||
|   my $address; | ||||
|   if ($opcode) { | ||||
|     ($address, $opcode) = split(/:\s+/, $opcode, 2); | ||||
|     $address = '16#' . $address . '# =>'; | ||||
|     $address = ' ' x ($vhdlAddressLength - length($address)) . $address; | ||||
|   } | ||||
|                                                                 # opcode to VHDL | ||||
|   if ($opcode) { | ||||
|     if ($comment eq '') { | ||||
|       $comment = ' ' . $opcode; | ||||
|     } | ||||
|     else { | ||||
|       $comment = ' ' . $opcode . ';' . $comment; | ||||
|     } | ||||
|                                                                    # replace NOP | ||||
|     $opcode =~ s/\ANOP/LOAD s0, s0/; | ||||
|                                                     # split opcodes and operands | ||||
|     $opcode =~ s/\s+/ /; | ||||
|     $opcode =~ s/\s+\Z//; | ||||
|     ($opcode, my $operand1, my $operand2) = split(/\s/, $opcode); | ||||
|     $operand1 =~ s/,//; | ||||
|     $operand1 =~ s/S/s/; | ||||
|     $operand2 =~ s/S/s/; | ||||
|     if ( ($opcode =~ m/\ASL/) or ($opcode =~ m/\ASR/) ) { | ||||
|       $operand2 = substr($opcode, 0, 3); | ||||
|       $opcode = 'SHIFT'; | ||||
|     } | ||||
|     if ( ($opcode =~ m/\ARL/)  or ($opcode =~ m/\ARR/) ) { | ||||
|       $operand2 = substr($opcode, 0, 2); | ||||
|       $opcode = 'ROT'; | ||||
|     } | ||||
|     if ( ($opcode eq 'JUMP') or ($opcode eq 'CALL') or ($opcode eq 'RETURN') ) { | ||||
|       unless ($operand2) { | ||||
|         unless ($opcode eq 'RETURN') { | ||||
|           $operand2 = $operand1; | ||||
|         } | ||||
|         $operand1 = 'AW'; # AlWays | ||||
|       } | ||||
|     } | ||||
|     #........................................................................... | ||||
|                                                                # opcodes to VHDL | ||||
|     $opcode =~ s/LOAD/opLoadC/; | ||||
|     $opcode =~ s/AND/opAndC/; | ||||
|     $opcode =~ s/XOR/opXorC/; | ||||
|     $opcode =~ s/ADDCY/opAddCyC/; | ||||
|     $opcode =~ s/SUBCY/opSubCyC/; | ||||
|     $opcode =~ s/ADD/opAddC/; | ||||
|     $opcode =~ s/SUB/opSubC/; | ||||
|     $opcode =~ s/SHIFT/opShRot/; | ||||
|     $opcode =~ s/ROT/opShRot/; | ||||
|     $opcode =~ s/COMPARE/opCompC/; | ||||
|     $opcode =~ s/TEST/opTestC/; | ||||
|     $opcode =~ s/FETCH/opFetchC/; | ||||
|     $opcode =~ s/STORE/opStoreC/; | ||||
|     $opcode =~ s/OR/opOrC/; | ||||
|     $opcode =~ s/INPUT/opInputC/; | ||||
|     $opcode =~ s/OUTPUT/opOutputC/; | ||||
|     $opcode =~ s/JUMP/brJump/; | ||||
|     $opcode =~ s/CALL/brCall/; | ||||
|     $opcode =~ s/RETURN/brRet/; | ||||
|     if ($operand2 =~ m/s[0-9A-F]/) { | ||||
|       $opcode =~ s/C\Z/R/; | ||||
|     } | ||||
|     $opcode = $opcode . ' ' x ($vhdlOpCodeLength - length($opcode)) . '& '; | ||||
|     #........................................................................... | ||||
|                                                      # register as first operand | ||||
|     if ($operand1 =~ m/s[0-9A-F]/) { | ||||
|       $operand1 =~ s/\As//; | ||||
|       $operand1 = '"' . toBinary($operand1, $registerAddressBitNb) . '"'; | ||||
|     } | ||||
|                                                                 # test condition | ||||
|     $operand1 =~ s/NC/brNC/; | ||||
|     $operand1 =~ s/NZ/brNZ/; | ||||
|     $operand1 =~ s/\AC/brC/; | ||||
|     $operand1 =~ s/\AZ/brZ/; | ||||
|     $operand1 =~ s/AW/brDo/; | ||||
|     if ($opcode =~ m/brRet/) { | ||||
|       $operand2 = 0; | ||||
|     } | ||||
|     if ($operand2 eq '') { | ||||
|       $operand1 = $operand1 . ','; | ||||
|     } | ||||
|     $operand1 = $operand1 . ' ' x ($vhdlOperand1Length - length($operand1)); | ||||
|     unless ($operand2 eq '') { | ||||
|       $operand1 = $operand1 . '& '; | ||||
|     } | ||||
| #print "|$opcode| |$operand1| |$operand2|\n"; | ||||
|     #........................................................................... | ||||
|                                                     # register as second operand | ||||
|     $operand2 =~ s/\A\((.*)\)\Z/$1/; | ||||
|     if ($operand2 =~ m/s[0-9A-F]/) { | ||||
|       $operand2 =~ s/\As//; | ||||
|       $operand2 = toBinary($operand2, $registerAddressBitNb); | ||||
|       if ($registerBitNb > $registerAddressBitNb) { | ||||
|         $operand2 = $operand2 . '-' x ($registerBitNb - $registerAddressBitNb); | ||||
|         if ($zeroDontCares) { | ||||
|           $operand2 =~ s/\-/0/g; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|                                                      # address as second operand | ||||
|     elsif ($opcode =~ m/\Abr/) { | ||||
|       my $fill = ''; | ||||
|       if ($binaryBranchInstructionLength < $binaryInstructionLength) { | ||||
|         $fill = '-' x ($binaryInstructionLength - $binaryBranchInstructionLength); | ||||
|         if ($zeroDontCares) { | ||||
|           $fill =~ s/\-/0/g; | ||||
|         } | ||||
|       } | ||||
|       if ( ($opcode =~ m/Ret/) ) { | ||||
|         $operand2 = $fill . '-' x $addressBitNb; | ||||
|       } | ||||
|       else { | ||||
|         $operand2 = $fill . toBinary(hex($operand2), $addressBitNb); | ||||
|       } | ||||
|     } | ||||
|                                                   # shift and rotate operators | ||||
|     elsif ($opcode =~ m/opShRot/) { | ||||
|       $operand2 =~ s/SL0/shRotL & shRotLd0/; | ||||
|       $operand2 =~ s/SL1/shRotL & shRotLd1/; | ||||
|       $operand2 =~ s/SLX/shRotL & shRotLdL/; | ||||
|       $operand2 =~ s/SLA/shRotL & shRotLdC/; | ||||
|       $operand2 =~ s/SR0/shRotR & shRotLd0/; | ||||
|       $operand2 =~ s/SR1/shRotR & shRotLd1/; | ||||
|       $operand2 =~ s/SRX/shRotR & shRotLdM/; | ||||
|       $operand2 =~ s/SRA/shRotR & shRotLdC/; | ||||
|       $operand2 =~ s/RL/shRotL & shRotLdH/; | ||||
|       $operand2 =~ s/RR/shRotR & shRotLdL/; | ||||
|     } | ||||
|                                                   # constant as second operand | ||||
|     else { | ||||
|       $operand2 = toBinary(hex($operand2), $registerBitNb); | ||||
|       if ($registerAddressBitNb > $registerBitNb) { | ||||
|         $operand2 = '-' x ($registerAddressBitNb - $registerBitNb) . $operand2; | ||||
|       } | ||||
|     } | ||||
|     unless ($opcode =~ m/opShRot/) { | ||||
|       $operand2 = '"' . $operand2 . '"'; | ||||
|     } | ||||
|                                                           # add separator at end | ||||
|     if ($operand2) { | ||||
|       $operand2 = $operand2 . ','; | ||||
|     } | ||||
|     #........................................................................... | ||||
|                                                # concatenate opcode and operands | ||||
|     $opcode = $opcode . $operand1 . $operand2; | ||||
|   } | ||||
|   else { | ||||
|     $address = ' ' x $vhdlAddressLength; | ||||
|   } | ||||
|                                                                # print VHDL code | ||||
|   if ($keepComments == 0) { | ||||
|     if ($opcode) { | ||||
|       print vhdlFile "$address $opcode\n"; | ||||
|     } | ||||
|   } | ||||
|   else { | ||||
|     $opcode = $opcode . ' ' x ($vhdlTotalLength - length($opcode)); | ||||
|     if ($comment) { | ||||
|       $comment =~ s/\s+\Z//; | ||||
|       print vhdlFile "$address $opcode--$comment\n"; | ||||
|     } | ||||
|     else { | ||||
|       print vhdlFile "$address $opcode\n"; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| close(asm2File); | ||||
| print vhdlFile <<DONE; | ||||
|     others => (others => '0') | ||||
|   ); | ||||
|  | ||||
| BEGIN | ||||
|  | ||||
|   process (clock) | ||||
|   begin | ||||
|     if rising_edge(clock) then | ||||
|       if en = '1' then | ||||
|         dataOut <= memoryArray(to_integer(address)); | ||||
|       end if; | ||||
|     end if; | ||||
|   end process; | ||||
|  | ||||
| END ARCHITECTURE mapped; | ||||
| DONE | ||||
| close(vhdlFile); | ||||
|  | ||||
| #------------------------------------------------------------------------------- | ||||
| # Delete original file and copy VHDL file | ||||
| # | ||||
| if ($verbose > 0) { | ||||
|   print "Copying $vhdlFileSpec to $outFileSpec\n"; | ||||
| } | ||||
|  | ||||
| use File::Copy; | ||||
| unlink($outFileSpec); | ||||
| copy($vhdlFileSpec, $outFileSpec) or die "File cannot be copied."; | ||||
| #rename($vhdlFileSpec, $outFileSpec); | ||||
|  | ||||
| if ($verbose > 0) { | ||||
|   print "$separator\n"; | ||||
| } | ||||
							
								
								
									
										1198
									
								
								Libs/NanoBlaze/hdl/nanoPascal.pl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1198
									
								
								Libs/NanoBlaze/hdl/nanoPascal.pl
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										342
									
								
								Libs/NanoBlaze/hdl/nanoTest.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										342
									
								
								Libs/NanoBlaze/hdl/nanoTest.asm
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,342 @@ | ||||
|                 ;=============================================================== | ||||
|                 ; nanoTest.asm | ||||
|                 ;   Used for checking the NanoBlaze instruction set | ||||
|                 ;=============================================================== | ||||
|                 ; 1) Test logical operations with direct values | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								LOAD      s7, 01 | ||||
|                 CONSTANT  testPattern, 0F | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "LOAD", "AND" | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								LOAD      s0, testPattern | ||||
| 								AND       s0, 33 | ||||
| 								COMPARE   s0, 03 | ||||
| 								JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "OR" | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								LOAD      s1, testPattern | ||||
| 								OR        s1, 33 | ||||
| 								COMPARE   s1, 3F | ||||
| 								JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "XOR" | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								LOAD      s2, testPattern | ||||
| 								XOR       s2, 33 | ||||
| 								COMPARE   s2, 3C | ||||
| 								JUMP      NZ, error | ||||
|                 ;=============================================================== | ||||
|                 ; 2) Test logical operations with registers | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "LOAD" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 33 | ||||
|                 LOAD      s3, s0 | ||||
|                 COMPARE   s3, 33 | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "AND" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 0F | ||||
|                 AND       s0, s3 | ||||
|                 COMPARE   s0, 03 | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "OR" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s1, 0F | ||||
|                 OR        s1, s3 | ||||
|                 COMPARE   s1, 3F | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "XOR" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s2, 0F | ||||
|                 XOR       s2, s3 | ||||
|                 COMPARE   s2, 3C | ||||
|                 JUMP      NZ, error | ||||
|                 ;=============================================================== | ||||
|                 ; 3) Test arithmetic operations with constants | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "ADD" and "ADDCY" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 0F | ||||
|                 ADD       s0, 31        ;  40 | ||||
|                 ADDCY     s0, F0        ; 130 | ||||
|                 ADDCY     s0, F0        ; 121 | ||||
|                 ADD       s0, 0F        ;  30 | ||||
|                 COMPARE   s0, 30 | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "SUB" and "SUBCY" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s1, 0F | ||||
|                 SUB       s1, 0C        ;  03 | ||||
|                 SUBCY     s1, F0        ; 113 | ||||
|                 SUBCY     s1, F0        ;  22 | ||||
|                 SUB       s1, 01        ;  21 | ||||
|                 COMPARE   s1, 21 | ||||
|                 JUMP      NZ, error | ||||
|                 ;=============================================================== | ||||
|                 ; 4) Test arithmetic operations with registers | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "ADD" and "ADDCY" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 0F | ||||
|                 LOAD      s1, 31 | ||||
|                 LOAD      s2, F0 | ||||
|                 LOAD      s3, 0F | ||||
|                 ADD       s0, s1        ;  40 | ||||
|                 ADDCY     s0, s2        ; 130 | ||||
|                 ADDCY     s0, s2        ; 121 | ||||
|                 ADD       s0, s3        ;  30 | ||||
|                 COMPARE   s0, 30 | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "SUB" and "SUBCY" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s1, 0F | ||||
|                 LOAD      s0, 0C | ||||
|                 LOAD      s2, F0 | ||||
|                 LOAD      s3, 01 | ||||
|                 SUB       s1, s0        ;  03 | ||||
|                 SUBCY     s1, s2        ; 113 | ||||
|                 SUBCY     s1, s2        ;  22 | ||||
|                 SUB       s1, s3        ;  21 | ||||
|                 COMPARE   s1, 21 | ||||
|                 JUMP      NZ, error | ||||
|                 ;=============================================================== | ||||
|                 ; 5) Test shifts | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test shift right | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 0F        ; 0F | ||||
|                 SR0       s0            ; 07 | ||||
|                 SRX       s0            ; 03 | ||||
|                 SR1       s0            ; 81 | ||||
|                 SRX       s0            ; C0, C=1 | ||||
|                 SRA       s0            ; E0, C=0 | ||||
|                 SRA       s0            ; 70 | ||||
|                 COMPARE   s0, 70 | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test shift left | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s1, F0        ; FO | ||||
|                 SL0       s1            ; E0 | ||||
|                 SLX       s1            ; C0 | ||||
|                 SL1       s1            ; 81 | ||||
|                 SLX       s1            ; 03, C=1 | ||||
|                 SLA       s1            ; 07, C=0 | ||||
|                 SLA       s1            ; 0E | ||||
|                 COMPARE   s1, 0E | ||||
|                 JUMP      NZ, error | ||||
|                 ;=============================================================== | ||||
|                 ; 6) Test comparison operators | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "COMPARE" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 0F | ||||
|                 COMPARE   s0, F0        ; A < B => C=1 | ||||
|                 JUMP      NC, error | ||||
|                 COMPARE   s0, F0        ; A < B => Z=0 | ||||
|                 JUMP      Z, error | ||||
|                 COMPARE   s0, s0        ; A = B => Z=1 | ||||
|                 JUMP      NZ, error | ||||
|                 COMPARE   s0, 08        ; A > B => C=0 | ||||
|                 JUMP      C, error | ||||
|                 COMPARE   s0, 08        ; A > B => Z=0 | ||||
|                 JUMP      Z, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "TEST" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 0F | ||||
|                 TEST      s0, F0        ; AND is 00 => Z=1 | ||||
|                 JUMP      NZ, error | ||||
|                 TEST      s0, FF        ; AND is 0F => Z=0 | ||||
|                 JUMP      Z, error | ||||
|                 ;=============================================================== | ||||
|                 ; 7) Test INPUT and OUTPUT operators | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "INPUT" and "OUTPUT" direct | ||||
|                 ; | ||||
|                 ; The testbench should invert the word written at address FC. | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, AA | ||||
|                 OUTPUT    s0, FC | ||||
|                 INPUT     s1, FC | ||||
|                 COMPARE   s1, 55 | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "INPUT" and "OUTPUT" indexed | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, CC | ||||
|                 LOAD      s2, FC | ||||
|                 OUTPUT    s0, (s2) | ||||
|                 INPUT     s1, (s2) | ||||
|                 COMPARE   s1, 33 | ||||
|                 JUMP      NZ, error | ||||
|                 ;=============================================================== | ||||
|                 ; 8) Test STORE and FETCH operators | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "STORE" and "FETCH" direct | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 0F | ||||
|                 STORE     s0, 03 | ||||
|                 FETCH     s1, 03 | ||||
|                 COMPARE   s1, 0F | ||||
|                 JUMP      NZ, error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "STORE" and "FETCH" indexed | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, F0 | ||||
|                 LOAD      s2, 04 | ||||
|                 STORE     s0, (s2) | ||||
|                 FETCH     s1, (s2) | ||||
|                 COMPARE   s1, F0 | ||||
|                 JUMP      NZ, error | ||||
|                 ;=============================================================== | ||||
|                 ; 9) Test JUMP instructions | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "JUMP NC" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, F0 | ||||
|                 ADD       s0, 00        ; s0=F0, C=0, Z=0 | ||||
|                 JUMP      NC, continue1 | ||||
|                 JUMP      error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "JUMP NZ" | ||||
|                 ;--------------------------------------------------------------- | ||||
|      continue1: ADD       s0, 00        ; s0=F0, C=0, Z=0 | ||||
|                 JUMP      NZ, continue2 | ||||
|                 JUMP      error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "JUMP C" | ||||
|                 ;--------------------------------------------------------------- | ||||
|      continue2: ADD       s0, F0        ; s0=E0, C=1, Z=0 | ||||
|                 JUMP      C, continue3 | ||||
|                 JUMP      error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "JUMP Z" | ||||
|                 ;--------------------------------------------------------------- | ||||
|      continue3: SUB       s0, E0        ; s0=00, C=0, Z=1 | ||||
|                 JUMP      Z, continue4 | ||||
|                 JUMP      error | ||||
|      continue4: NOP | ||||
|                 ;=============================================================== | ||||
|                 ; 10) Test call instructions | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; define subroutine | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 JUMP      continue5 | ||||
|       subRetDo: ADD       s0, 01 | ||||
|                 RETURN | ||||
|                 JUMP      error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "CALL" | ||||
|                 ;--------------------------------------------------------------- | ||||
|      continue5: LOAD      s0, 00 | ||||
|                 LOAD      s1, F0 | ||||
|                 CALL      subRetDo      ; s0=01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "CALL NC" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ADD       s1, 00        ; s1=F0, C=0, Z=0 | ||||
|                 CALL      NC, subRetDo  ; s0=02 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "CALL NZ" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ADD       s1, 00        ; s1=F0, C=0, Z=0 | ||||
|                 CALL      NZ, subRetDo  ; s0=03 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "CALL C" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ADD       s1, F0        ; s0=E0, C=1, Z=0 | ||||
|                 CALL      C, subRetDo   ; s0=04 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "CALL Z" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 SUB       s1, E0        ; s0=00, C=0, Z=1 | ||||
|                 CALL      Z, subRetDo   ; s0=05 | ||||
|                 COMPARE   s0, 05 | ||||
|                 jump      nz, error | ||||
|                 ;=============================================================== | ||||
|                 ; 11) Test call return instructions | ||||
|                 ;--------------------------------------------------------------- | ||||
| 								ADD       s7, 01 | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; define subroutines | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 JUMP      continue6 | ||||
|       subRetNC: ADD       s0, 01 | ||||
|                 RETURN    NC | ||||
|                 JUMP      error | ||||
|       subRetNZ: ADD       s0, 01 | ||||
|                 RETURN    NZ | ||||
|                 JUMP      error | ||||
|        subRetC: ADD       s0, 01 | ||||
|                 RETURN    C | ||||
|                 JUMP      error | ||||
|        subRetZ: ADD       s0, 01 | ||||
|                 RETURN    Z | ||||
|                 JUMP      error | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "RETURN NC" | ||||
|                 ;--------------------------------------------------------------- | ||||
|      continue6: LOAD      s0, 00        ; increment will give C=0, Z=0 | ||||
|                 CALL      NC, subRetNC | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "RETURN NZ" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 00        ; increment will give C=0, Z=0 | ||||
|                 CALL      NZ, subRetNZ | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "RETURN C" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, FF        ; increment will give C=1, Z=1 | ||||
|                 CALL      C, subRetC | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 ; Test "RETURN Z" | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, FF        ; increment will give C=1, Z=1 | ||||
|                 CALL      Z, subRetZ | ||||
|                 ;=============================================================== | ||||
|                 ; End of tests | ||||
|                 ; | ||||
|                 ; The testbench should react if value 1 is written to address 00. | ||||
|                 ;--------------------------------------------------------------- | ||||
|                 LOAD      s0, 01 | ||||
|                 OUTPUT    s0, 00 | ||||
|                 JUMP      endOfMemory | ||||
|                 ;=============================================================== | ||||
|                 ; Assert error | ||||
|                 ; | ||||
|                 ; The testbench should react if value 0 is written to address 00. | ||||
|                 ;--------------------------------------------------------------- | ||||
| ADDRESS 3FD | ||||
|          error: LOAD      s0, 00 | ||||
|                 OUTPUT    s0, 00 | ||||
|                 ;=============================================================== | ||||
|                 ; End of instruction memory | ||||
|                 ;--------------------------------------------------------------- | ||||
|    endOfMemory: JUMP      endOfMemory | ||||
							
								
								
									
										368
									
								
								Libs/NanoBlaze/hdl/nanoTest.pas
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								Libs/NanoBlaze/hdl/nanoTest.pas
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,368 @@ | ||||
| { | ||||
|   beamer.pas | ||||
|  | ||||
|   The beamer controller polls the UART to get commands and provides the | ||||
|   corresponding replies. | ||||
| } | ||||
|  | ||||
| program BeamerControl; | ||||
|  | ||||
| {==============================================================================} | ||||
| { Constants                                                                    } | ||||
| {==============================================================================} | ||||
|   const | ||||
|     clockFrequency      = 66E6; | ||||
|     gpioBaseAddress     = $0000; | ||||
|     gpioDataOffset        = $0000; | ||||
|     gpioEnableOffset      = $0001; | ||||
|     uartBaseAddress     = $0010; | ||||
|     uartBaudOffset        = $0002; | ||||
|     uartStatusOffset      = $0001; | ||||
|     uartDataReady           = $0001; | ||||
|     uartSending             = $0002; | ||||
|     uartBaudRate        = 1E6; | ||||
|     uartBaudCount         = clockFrequency / uartBaudRate; | ||||
|     uartPollDelay         = uartBaudCount / 2; | ||||
|     uartTimeout         = 10; | ||||
|     commandHeader       = $AA; | ||||
|     commandNack         = $00; | ||||
|     commandWriteMem     = $03; | ||||
|     commandReadMem      = $04; | ||||
|     commandWriteLength  = 4; | ||||
|     commandReadLength   = 2; | ||||
|     beamerBaseAddress   = $0020; | ||||
|     beamerCtlOffset       = $0000; | ||||
|     beamerSpeedOffset     = $0001; | ||||
|     beamerCtlInit         = $0401; | ||||
|     beamerSpeedInit       = $0004; | ||||
|     commStIdle            = $0000; | ||||
|     commStGetPacketId     = $0001; | ||||
|     commStGetCommandId    = $0002; | ||||
|     commStGetDataLength   = $0003; | ||||
|     commStGetData         = $0004; | ||||
|     commStGetChecksum     = $0005; | ||||
|     commStExecuteCommand  = $0006; | ||||
|     commStSendHeader      = $0007; | ||||
|     commStSendPacketId    = $0008; | ||||
|     commStSendCommandId   = $0009; | ||||
|     commStSendDataLength  = $000A; | ||||
|     commStSendData        = $000B; | ||||
|     commStSendChecksum    = $000C; | ||||
|  | ||||
| {==============================================================================} | ||||
| { Variables                                                                    } | ||||
| {==============================================================================} | ||||
|   var | ||||
|     communicationState : word; | ||||
|     uartByte: uint8; | ||||
|  | ||||
| {==============================================================================} | ||||
| { Procedures and functions                                                     } | ||||
| {==============================================================================} | ||||
|  | ||||
|   {============================================================================} | ||||
|   { Register-level functions                                                    } | ||||
|   {============================================================================} | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Registers initializations                                                  } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   procedure initRegisters; | ||||
|     const | ||||
|       gpioValue = $AA; | ||||
|       gpioEnablemask = $0F; | ||||
|   begin | ||||
|                                                              { initialize GPIO } | ||||
|     mem[gpioBaseAddress+gpioDataOffset] := gpioValue; | ||||
|     mem[gpioBaseAddress+gpioEnableOffset] := gpioEnablemask; | ||||
|                                                              { initialize UART } | ||||
|     mem[uartBaseAddress+uartBaudOffset] := uartBaudCount; | ||||
|                                                 { initialize beamer peripheral } | ||||
|     mem[beamerBaseAddress+beamerCtlOffset] := beamerCtlInit; | ||||
|     mem[beamerBaseAddress+beamerSpeedOffset] := beamerSpeedInit; | ||||
|   end; | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Get byte from serial port with timeout                                     } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   function getSerialPortByte(var uartByte: uint8) : word; | ||||
|     var | ||||
|       dataReady: uint8; | ||||
|       pollCount: word; | ||||
|   begin | ||||
|                             { poll until data byte available or timeout occured} | ||||
|     pollCount := uartPollDelay; | ||||
|     dataReady := 0; | ||||
|     while dataReady = 0 do | ||||
|       begin | ||||
|                                                         { read status register } | ||||
|         dataReady := mem[uartBaseAddress+uartStatusOffset] and uartDataReady; | ||||
|                            { spend time in order not to overcharge the AHB bus } | ||||
|         if dataReady = 0 then | ||||
|           begin | ||||
|                                                            { check for timeout } | ||||
|             pollCount := pollCount -1; | ||||
|             if pollCount = 0 then | ||||
|               dataReady := $FF; | ||||
|                         { spend time in order not to overcharge the system bus } | ||||
|             for index := 1 to uartPollDelay do | ||||
|               noOperation; | ||||
|           end; | ||||
|       end; | ||||
|                                                              { function return } | ||||
|     if dataReady = $FF then | ||||
|                                                               { return timeout } | ||||
|       getSerialPortByte := 1; | ||||
|     else | ||||
|                                             { read data register and return it } | ||||
|       begin | ||||
|         uartByte := mem[uartBaseAddress]; | ||||
|         getSerialPortByte := 0; | ||||
|       end; | ||||
|   end; | ||||
|  | ||||
|   {----------------------------------------------------------------------------} | ||||
|   { Send byte to serial port with timeout                                      } | ||||
|   {----------------------------------------------------------------------------} | ||||
|   function sendSerialPort(var uartByte : uint8) : word; | ||||
|     var | ||||
|       dataReady: uint8; | ||||
|       statusByte: uint8; | ||||
|       pollCount: word; | ||||
|   begin | ||||
|                                                     { poll until ready to send } | ||||
|     pollCount := uartPollDelay; | ||||
|     statusByte := mem[uartBaseAddress+uartStatusOffset] and uartSending; | ||||
|     while statusByte = 0 do | ||||
|       begin | ||||
|                                                            { check for timeout } | ||||
|         pollCount := pollCount -1; | ||||
|         if pollCount = 0 then | ||||
|           dataReady := $FF; | ||||
|                         { spend time in order not to overcharge the system bus } | ||||
|         for index := 1 to uartPollDelay do | ||||
|           noOperation; | ||||
|                                                         { read status register } | ||||
|         statusByte := mem[uartBaseAddress+uartStatusOffset] and uartSending; | ||||
|       end; | ||||
|                                                              { function return } | ||||
|     if dataReady = $FF then | ||||
|                                                               { return timeout } | ||||
|       sendSerialPort := 1; | ||||
|     else | ||||
|                                            { write data register and return it } | ||||
|       begin | ||||
|         mem[uartBaseAddress] := uartByte; | ||||
|         sendSerialPort := 0; | ||||
|       end; | ||||
|   end; | ||||
|  | ||||
|   {============================================================================} | ||||
|   { Communication state machine                                                                } | ||||
|   {============================================================================} | ||||
|   procedure updateStateMachine( | ||||
|     var communicationState : word; | ||||
|     var uartByte: uint8 | ||||
|   ); | ||||
|     var | ||||
|       communicationNextState : word; | ||||
|       uartStatus: word; | ||||
|       packetId, commandId : uint8; | ||||
|       checksum : uint8; | ||||
|       dataLength, dataCount, data1, data2, data3, data4 : uint8; | ||||
|       memAddress, memData : word; | ||||
|   begin | ||||
|                                                                         { idle } | ||||
|     if communicationState = commStIdle then | ||||
|       begin | ||||
|         uartStatus := getSerialPortByte(var uartByte: uint8); | ||||
|         if (uartStatus = 0) and (uartByte = commandHeader) then | ||||
|           begin | ||||
|             checksum := uartByte; | ||||
|             communicationNextState := commStGetPacketId; | ||||
|           end; | ||||
|       end; | ||||
|                                                                { get packet id } | ||||
|     else if communicationState = commStGetPacketId then | ||||
|       begin | ||||
|         uartStatus := getSerialPortByte(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             packetId := uartByte; | ||||
|             checksum := checksum + uartByte; | ||||
|             communicationNextState := commStGetCommandId; | ||||
|           end; | ||||
|       end; | ||||
|                                                               { get command id } | ||||
|     else if communicationState = commStGetCommandId then | ||||
|       begin | ||||
|         uartStatus := getSerialPortByte(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             commandId := uartByte; | ||||
|             checksum := checksum + uartByte; | ||||
|             communicationNextState := commStGetDataLength; | ||||
|           end; | ||||
|       end; | ||||
|                                                              { get data length } | ||||
|     else if communicationState = commStGetDataLength then | ||||
|       begin | ||||
|         uartStatus := getSerialPortByte(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             dataLength := uartByte; | ||||
|             checksum := checksum + uartByte; | ||||
|             dataCount := dataLength; | ||||
|             communicationNextState := commStGetData; | ||||
|           end; | ||||
|       end; | ||||
|                                                                     { get data } | ||||
|     else if communicationState = commStGetData then | ||||
|       begin | ||||
|         uartStatus := getSerialPortByte(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             data1 := data2; | ||||
|             data2 := data3; | ||||
|             data3 := data4; | ||||
|             data4 := uartByte; | ||||
|             checksum := checksum + uartByte; | ||||
|             dataCount := dataCount-1; | ||||
|             if dataCount = 0 then | ||||
|               communicationNextState := commStGetChecksum; | ||||
|           end; | ||||
|       end; | ||||
|                                                                 { get checksum } | ||||
|     else if communicationState = commStGetChecksum then | ||||
|       begin | ||||
|         uartStatus := getSerialPortByte(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             if uartByte = checksum then | ||||
|               communicationState := commStExecuteCommand; | ||||
|             else | ||||
|               begin | ||||
|                 commandId := commandNack; | ||||
|                 dataLength := 0; | ||||
|                 communicationNextState := commStSendHeader; | ||||
|               end; | ||||
|           end; | ||||
|       end; | ||||
|                                                              { execute command } | ||||
|     else if communicationState = commStExecuteCommand then | ||||
| begin | ||||
|       if (commandId = commandWriteMem) and (dataLength = commandWriteLength) then | ||||
|         begin | ||||
|           memAddress := data1 + (data2 shl 8); | ||||
|           memData    := data3 + (data4 shl 8); | ||||
|           mem[memAddress] := memData; | ||||
|           dataLength := 0; | ||||
|           communicationNextState := commStSendHeader; | ||||
|         end; | ||||
|       else if (commandId = commandReadMem) and (dataLength = commandReadLength) then | ||||
|         begin | ||||
|           memAddress := data3 + (data4 shl 8); | ||||
|           memData := mem[memAddress]; | ||||
|           dataLength := 2; | ||||
|           data1 := memData and $00FF; | ||||
|           data2 := memData shr 8; | ||||
|           communicationNextState := commStSendHeader; | ||||
|         end; | ||||
|       else | ||||
|         begin | ||||
|           commandId := commandNack; | ||||
|           dataLength := 0; | ||||
|           communicationNextState := commStSendHeader; | ||||
|         end; | ||||
| end; | ||||
|                                                                  { send header } | ||||
|     else if communicationState = commStSendHeader then | ||||
|       begin | ||||
|         uartByte := commandHeader; | ||||
|         uartStatus := sendSerialPort(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             checksum := uartByte; | ||||
|             communicationNextState := commStSendPacketId; | ||||
|           end; | ||||
|       end; | ||||
|                                                               { send packet id } | ||||
|     else if communicationState = commStSendPacketId then | ||||
|       begin | ||||
|         uartByte := packetId; | ||||
|         uartStatus := sendSerialPort(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             checksum := checksum + uartByte; | ||||
|             communicationNextState := commStSendCommandId; | ||||
|           end; | ||||
|       end; | ||||
|                                                              { send command id } | ||||
|     else if communicationState = commStSendCommandId then | ||||
|       begin | ||||
|         uartByte := commandId; | ||||
|         uartStatus := sendSerialPort(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             checksum := checksum + uartByte; | ||||
|             communicationNextState := commStSendDataLength; | ||||
|           end; | ||||
|       end; | ||||
|                                                             { send data length } | ||||
|     else if communicationState = commStSendDataLength then | ||||
|       begin | ||||
|         uartByte := dataLength; | ||||
|         dataCount := dataLength; | ||||
|         uartStatus := sendSerialPort(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           begin | ||||
|             checksum := checksum + uartByte; | ||||
|             communicationNextState := commStSendData; | ||||
|           end; | ||||
|       end; | ||||
|                                                                    { send data } | ||||
|     else if communicationState = commStSendData then | ||||
|       begin | ||||
|         if dataCount > 0 then | ||||
|           begin | ||||
|             uartByte := data1; | ||||
|             data2 := data1; | ||||
|             data3 := data2; | ||||
|             data4 := data3; | ||||
|             uartStatus := sendSerialPort(var uartByte: uint8); | ||||
|             if uartStatus = 0 then | ||||
|               begin | ||||
|                 checksum := checksum + uartByte; | ||||
|                 dataCount := dataCount-1; | ||||
|               end; | ||||
|           end; | ||||
|         else | ||||
|           communicationNextState := commStSendChecksum; | ||||
|       end; | ||||
|                                                                { send checksum } | ||||
|     else if communicationState = commStSendChecksum then | ||||
|       begin | ||||
|         uartByte := checksum and $00FF; | ||||
|         uartStatus := sendSerialPort(var uartByte: uint8); | ||||
|         if uartStatus = 0 then | ||||
|           communicationNextState := commStIdle; | ||||
|       end; | ||||
|                                                                 { update state } | ||||
|     communicationState := communicationNextState; | ||||
|   end; | ||||
|  | ||||
| {==============================================================================} | ||||
| { Main program                                                                 } | ||||
| {==============================================================================} | ||||
| begin | ||||
|                                                     { initialize SoC registers } | ||||
|   initRegisters; | ||||
|                                       { initialize communication state machine } | ||||
|   communicationState := commStIdle; | ||||
|                                                                    { main loop } | ||||
|   while true do begin | ||||
|                                           { update communication state machine } | ||||
|     updateStateMachine(var communicationState : word; var uartByte : uint8); | ||||
|                                                            { check for timeout } | ||||
|   end; | ||||
| end. | ||||
							
								
								
									
										431
									
								
								Libs/NanoBlaze/hdl/nanoTest.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										431
									
								
								Libs/NanoBlaze/hdl/nanoTest.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,431 @@ | ||||
| ARCHITECTURE mapped OF programRom IS | ||||
|  | ||||
|   subtype opCodeType is std_ulogic_vector(5 downto 0); | ||||
|   constant opLoadC   : opCodeType := "000000"; | ||||
|   constant opLoadR   : opCodeType := "000001"; | ||||
|   constant opInputC  : opCodeType := "000100"; | ||||
|   constant opInputR  : opCodeType := "000101"; | ||||
|   constant opFetchC  : opCodeType := "000110"; | ||||
|   constant opFetchR  : opCodeType := "000111"; | ||||
|   constant opAndC    : opCodeType := "001010"; | ||||
|   constant opAndR    : opCodeType := "001011"; | ||||
|   constant opOrC     : opCodeType := "001100"; | ||||
|   constant opOrR     : opCodeType := "001101"; | ||||
|   constant opXorC    : opCodeType := "001110"; | ||||
|   constant opXorR    : opCodeType := "001111"; | ||||
|   constant opTestC   : opCodeType := "010010"; | ||||
|   constant opTestR   : opCodeType := "010011"; | ||||
|   constant opCompC   : opCodeType := "010100"; | ||||
|   constant opCompR   : opCodeType := "010101"; | ||||
|   constant opAddC    : opCodeType := "011000"; | ||||
|   constant opAddR    : opCodeType := "011001"; | ||||
|   constant opAddCyC  : opCodeType := "011010"; | ||||
|   constant opAddCyR  : opCodeType := "011011"; | ||||
|   constant opSubC    : opCodeType := "011100"; | ||||
|   constant opSubR    : opCodeType := "011101"; | ||||
|   constant opSubCyC  : opCodeType := "011110"; | ||||
|   constant opSubCyR  : opCodeType := "011111"; | ||||
|   constant opShRot   : opCodeType := "100000"; | ||||
|   constant opOutputC : opCodeType := "101100"; | ||||
|   constant opOutputR : opCodeType := "101101"; | ||||
|   constant opStoreC  : opCodeType := "101110"; | ||||
|   constant opStoreR  : opCodeType := "101111"; | ||||
|  | ||||
|   subtype shRotCinType is std_ulogic_vector(2 downto 0); | ||||
|   constant shRotLdC : shRotCinType := "00-"; | ||||
|   constant shRotLdM : shRotCinType := "01-"; | ||||
|   constant shRotLdL : shRotCinType := "10-"; | ||||
|   constant shRotLd0 : shRotCinType := "110"; | ||||
|   constant shRotLd1 : shRotCinType := "111"; | ||||
|  | ||||
|   constant registerAddressBitNb : positive := 4; | ||||
|   constant shRotPadLength : positive | ||||
|     := dataOut'length - opCodeType'length - registerAddressBitNb | ||||
|      - 1 - shRotCinType'length; | ||||
|   subtype shRotDirType is std_ulogic_vector(1+shRotPadLength-1 downto 0); | ||||
|   constant shRotL : shRotDirType := (0 => '0', others => '-'); | ||||
|   constant shRotR : shRotDirType := (0 => '1', others => '-'); | ||||
|  | ||||
|   subtype branchCodeType is std_ulogic_vector(4 downto 0); | ||||
|   constant brRet  : branchCodeType := "10101"; | ||||
|   constant brCall : branchCodeType := "11000"; | ||||
|   constant brJump : branchCodeType := "11010"; | ||||
|   constant brReti : branchCodeType := "11100"; | ||||
|   constant brEni  : branchCodeType := "11110"; | ||||
|  | ||||
|   subtype branchConditionType is std_ulogic_vector(2 downto 0); | ||||
|   constant brDo : branchConditionType := "000"; | ||||
|   constant brZ  : branchConditionType := "100"; | ||||
|   constant brNZ : branchConditionType := "101"; | ||||
|   constant brC  : branchConditionType := "110"; | ||||
|   constant brNC : branchConditionType := "111"; | ||||
|  | ||||
|   subtype memoryWordType is std_ulogic_vector(dataOut'range); | ||||
|   type memoryArrayType is array (0 to 2**address'length-1) of memoryWordType; | ||||
|  | ||||
|   signal memoryArray : memoryArrayType := ( | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 1) Test logical operations with direct values | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#000# => opLoadC   & "0111" & "00000001",   -- LOAD      s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "LOAD", "AND" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#001# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#002# => opAndC    & "0000" & "00110011",   -- AND       s0, 33 | ||||
|     16#003# => opCompC   & "0000" & "00000011",   -- COMPARE   s0, 03 | ||||
|     16#004# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "OR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#005# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#006# => opOrC     & "0001" & "00110011",   -- OR        s1, 33 | ||||
|     16#007# => opCompC   & "0001" & "00111111",   -- COMPARE   s1, 3F | ||||
|     16#008# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "XOR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#009# => opLoadC   & "0010" & "00001111",   -- LOAD      s2, 0F | ||||
|     16#00A# => opXorC    & "0010" & "00110011",   -- XOR       s2, 33 | ||||
|     16#00B# => opCompC   & "0010" & "00111100",   -- COMPARE   s2, 3C | ||||
|     16#00C# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 2) Test logical operations with registers | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#00D# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "LOAD" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#00E# => opLoadC   & "0000" & "00110011",   -- LOAD      s0, 33 | ||||
|     16#00F# => opLoadR   & "0011" & "0000----",   -- LOAD      s3, s0 | ||||
|     16#010# => opCompC   & "0011" & "00110011",   -- COMPARE   s3, 33 | ||||
|     16#011# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "AND" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#012# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#013# => opAndR    & "0000" & "0011----",   -- AND       s0, s3 | ||||
|     16#014# => opCompC   & "0000" & "00000011",   -- COMPARE   s0, 03 | ||||
|     16#015# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "OR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#016# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#017# => opOrR     & "0001" & "0011----",   -- OR        s1, s3 | ||||
|     16#018# => opCompC   & "0001" & "00111111",   -- COMPARE   s1, 3F | ||||
|     16#019# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "XOR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#01A# => opLoadC   & "0010" & "00001111",   -- LOAD      s2, 0F | ||||
|     16#01B# => opXorR    & "0010" & "0011----",   -- XOR       s2, s3 | ||||
|     16#01C# => opCompC   & "0010" & "00111100",   -- COMPARE   s2, 3C | ||||
|     16#01D# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 3) Test arithmetic operations with constants | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#01E# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "ADD" and "ADDCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#01F# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#020# => opAddC    & "0000" & "00110001",   -- ADD       s0, 31   ;  40 | ||||
|     16#021# => opAddCyC  & "0000" & "11110000",   -- ADDCY     s0, F0   ; 130 | ||||
|     16#022# => opAddCyC  & "0000" & "11110000",   -- ADDCY     s0, F0   ; 121 | ||||
|     16#023# => opAddC    & "0000" & "00001111",   -- ADD       s0, 0F   ;  30 | ||||
|     16#024# => opCompC   & "0000" & "00110000",   -- COMPARE   s0, 30 | ||||
|     16#025# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "SUB" and "SUBCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#026# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#027# => opSubC    & "0001" & "00001100",   -- SUB       s1, 0C   ;  03 | ||||
|     16#028# => opSubCyC  & "0001" & "11110000",   -- SUBCY     s1, F0   ; 113 | ||||
|     16#029# => opSubCyC  & "0001" & "11110000",   -- SUBCY     s1, F0   ;  22 | ||||
|     16#02A# => opSubC    & "0001" & "00000001",   -- SUB       s1, 01   ;  21 | ||||
|     16#02B# => opCompC   & "0001" & "00100001",   -- COMPARE   s1, 21 | ||||
|     16#02C# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 4) Test arithmetic operations with registers | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#02D# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "ADD" and "ADDCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#02E# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#02F# => opLoadC   & "0001" & "00110001",   -- LOAD      s1, 31 | ||||
|     16#030# => opLoadC   & "0010" & "11110000",   -- LOAD      s2, F0 | ||||
|     16#031# => opLoadC   & "0011" & "00001111",   -- LOAD      s3, 0F | ||||
|     16#032# => opAddR    & "0000" & "0001----",   -- ADD       s0, s1   ;  40 | ||||
|     16#033# => opAddCyR  & "0000" & "0010----",   -- ADDCY     s0, s2   ; 130 | ||||
|     16#034# => opAddCyR  & "0000" & "0010----",   -- ADDCY     s0, s2   ; 121 | ||||
|     16#035# => opAddR    & "0000" & "0011----",   -- ADD       s0, s3   ;  30 | ||||
|     16#036# => opCompC   & "0000" & "00110000",   -- COMPARE   s0, 30 | ||||
|     16#037# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "SUB" and "SUBCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#038# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#039# => opLoadC   & "0000" & "00001100",   -- LOAD      s0, 0C | ||||
|     16#03A# => opLoadC   & "0010" & "11110000",   -- LOAD      s2, F0 | ||||
|     16#03B# => opLoadC   & "0011" & "00000001",   -- LOAD      s3, 01 | ||||
|     16#03C# => opSubR    & "0001" & "0000----",   -- SUB       s1, s0   ;  03 | ||||
|     16#03D# => opSubCyR  & "0001" & "0010----",   -- SUBCY     s1, s2   ; 113 | ||||
|     16#03E# => opSubCyR  & "0001" & "0010----",   -- SUBCY     s1, s2   ;  22 | ||||
|     16#03F# => opSubR    & "0001" & "0011----",   -- SUB       s1, s3   ;  21 | ||||
|     16#040# => opCompC   & "0001" & "00100001",   -- COMPARE   s1, 21 | ||||
|     16#041# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 5) Test shifts | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#042# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test shift right | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#043# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F   ; 0F | ||||
|     16#044# => opShRot   & "0000" & shRotR & shRotLd0,-- SR0       s0       ; 07 | ||||
|     16#045# => opShRot   & "0000" & shRotR & shRotLdM,-- SRX       s0       ; 03 | ||||
|     16#046# => opShRot   & "0000" & shRotR & shRotLd1,-- SR1       s0       ; 81 | ||||
|     16#047# => opShRot   & "0000" & shRotR & shRotLdM,-- SRX       s0       ; C0, C=1 | ||||
|     16#048# => opShRot   & "0000" & shRotR & shRotLdC,-- SRA       s0       ; E0, C=0 | ||||
|     16#049# => opShRot   & "0000" & shRotR & shRotLdC,-- SRA       s0       ; 70 | ||||
|     16#04A# => opCompC   & "0000" & "01110000",   -- COMPARE   s0, 70 | ||||
|     16#04B# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test shift left | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#04C# => opLoadC   & "0001" & "11110000",   -- LOAD      s1, F0   ; FO | ||||
|     16#04D# => opShRot   & "0001" & shRotL & shRotLd0,-- SL0       s1       ; E0 | ||||
|     16#04E# => opShRot   & "0001" & shRotL & shRotLdL,-- SLX       s1       ; C0 | ||||
|     16#04F# => opShRot   & "0001" & shRotL & shRotLd1,-- SL1       s1       ; 81 | ||||
|     16#050# => opShRot   & "0001" & shRotL & shRotLdL,-- SLX       s1       ; 03, C=1 | ||||
|     16#051# => opShRot   & "0001" & shRotL & shRotLdC,-- SLA       s1       ; 07, C=0 | ||||
|     16#052# => opShRot   & "0001" & shRotL & shRotLdC,-- SLA       s1       ; 0E | ||||
|     16#053# => opCompC   & "0001" & "00001110",   -- COMPARE   s1, 0E | ||||
|     16#054# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 6) Test comparison operators | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#055# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "COMPARE" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#056# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#057# => opCompC   & "0000" & "11110000",   -- COMPARE   s0, F0   ; A < B => C=1 | ||||
|     16#058# => brJump    & brNC   & "1111111101", -- JUMP      NC, 3FD | ||||
|     16#059# => opCompC   & "0000" & "11110000",   -- COMPARE   s0, F0   ; A < B => Z=0 | ||||
|     16#05A# => brJump    & brZ    & "1111111101", -- JUMP      Z, 3FD | ||||
|     16#05B# => opCompR   & "0000" & "0000----",   -- COMPARE   s0, s0   ; A = B => Z=1 | ||||
|     16#05C# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|     16#05D# => opCompC   & "0000" & "00001000",   -- COMPARE   s0, 08   ; A > B => C=0 | ||||
|     16#05E# => brJump    & brC    & "1111111101", -- JUMP      C, 3FD | ||||
|     16#05F# => opCompC   & "0000" & "00001000",   -- COMPARE   s0, 08   ; A > B => Z=0 | ||||
|     16#060# => brJump    & brZ    & "1111111101", -- JUMP      Z, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "TEST" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#061# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#062# => opTestC   & "0000" & "11110000",   -- TEST      s0, F0   ; AND is 00 => Z=1 | ||||
|     16#063# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|     16#064# => opTestC   & "0000" & "11111111",   -- TEST      s0, FF   ; AND is 0F => Z=0 | ||||
|     16#065# => brJump    & brZ    & "1111111101", -- JUMP      Z, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 7) Test INPUT and OUTPUT operators | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#066# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "INPUT" and "OUTPUT" direct | ||||
|                                                   -- | ||||
|                                                   -- The testbench should invert the word written at address FC. | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#067# => opLoadC   & "0000" & "10101010",   -- LOAD      s0, AA | ||||
|     16#068# => opOutputC & "0000" & "11111100",   -- OUTPUT    s0, FC | ||||
|     16#069# => opInputC  & "0001" & "11111100",   -- INPUT     s1, FC | ||||
|     16#06A# => opCompC   & "0001" & "01010101",   -- COMPARE   s1, 55 | ||||
|     16#06B# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "INPUT" and "OUTPUT" indexed | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#06C# => opLoadC   & "0000" & "11001100",   -- LOAD      s0, CC | ||||
|     16#06D# => opLoadC   & "0010" & "11111100",   -- LOAD      s2, FC | ||||
|     16#06E# => opOutputR & "0000" & "0010----",   -- OUTPUT    s0, (S2) | ||||
|     16#06F# => opInputR  & "0001" & "0010----",   -- INPUT     s1, (S2) | ||||
|     16#070# => opCompC   & "0001" & "00110011",   -- COMPARE   s1, 33 | ||||
|     16#071# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 8) Test STORE and FETCH operators | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#072# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "STORE" and "FETCH" direct | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#073# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#074# => opStoreC  & "0000" & "00000011",   -- STORE     s0, 03 | ||||
|     16#075# => opFetchC  & "0001" & "00000011",   -- FETCH     s1, 03 | ||||
|     16#076# => opCompC   & "0001" & "00001111",   -- COMPARE   s1, 0F | ||||
|     16#077# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "STORE" and "FETCH" indexed | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#078# => opLoadC   & "0000" & "11110000",   -- LOAD      s0, F0 | ||||
|     16#079# => opLoadC   & "0010" & "00000100",   -- LOAD      s2, 04 | ||||
|     16#07A# => opStoreR  & "0000" & "0010----",   -- STORE     s0, (S2) | ||||
|     16#07B# => opFetchR  & "0001" & "0010----",   -- FETCH     s1, (S2) | ||||
|     16#07C# => opCompC   & "0001" & "11110000",   -- COMPARE   s1, F0 | ||||
|     16#07D# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 9) Test JUMP instructions | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#07E# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP NC" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#07F# => opLoadC   & "0000" & "11110000",   -- LOAD      s0, F0 | ||||
|     16#080# => opAddC    & "0000" & "00000000",   -- ADD       s0, 00   ; s0=F0, C=0, Z=0 | ||||
|     16#081# => brJump    & brNC   & "0010000011", -- JUMP      NC, 083 | ||||
|     16#082# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP NZ" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue1_: | ||||
|     16#083# => opAddC    & "0000" & "00000000",   -- ADD       s0, 00   ; s0=F0, C=0, Z=0 | ||||
|     16#084# => brJump    & brNZ   & "0010000110", -- JUMP      NZ, 086 | ||||
|     16#085# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP C" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue2_: | ||||
|     16#086# => opAddC    & "0000" & "11110000",   -- ADD       s0, F0   ; s0=E0, C=1, Z=0 | ||||
|     16#087# => brJump    & brC    & "0010001001", -- JUMP      C, 089 | ||||
|     16#088# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP Z" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue3_: | ||||
|     16#089# => opSubC    & "0000" & "11100000",   -- SUB       s0, E0   ; s0=00, C=0, Z=1 | ||||
|     16#08A# => brJump    & brZ    & "0010001100", -- JUMP      Z, 08C | ||||
|     16#08B# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _continue4_: | ||||
|     16#08C# => opLoadR   & "0000" & "0000----",   -- NOP | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 10) Test call instructions | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#08D# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- define subroutine | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#08E# => brJump    & brDo   & "0010010010", -- JUMP      092 | ||||
|                                                   -- _subRetDo_: | ||||
|     16#08F# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#090# => brRet     & brDo   & "----------", -- RETURN | ||||
|     16#091# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue5_: | ||||
|     16#092# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00 | ||||
|     16#093# => opLoadC   & "0001" & "11110000",   -- LOAD      s1, F0 | ||||
|     16#094# => brCall    & brDo   & "0010001111", -- CALL      08F      ; s0=01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL NC" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#095# => opAddC    & "0001" & "00000000",   -- ADD       s1, 00   ; s1=F0, C=0, Z=0 | ||||
|     16#096# => brCall    & brNC   & "0010001111", -- CALL      NC, 08F  ; s0=02 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL NZ" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#097# => opAddC    & "0001" & "00000000",   -- ADD       s1, 00   ; s1=F0, C=0, Z=0 | ||||
|     16#098# => brCall    & brNZ   & "0010001111", -- CALL      NZ, 08F  ; s0=03 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL C" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#099# => opAddC    & "0001" & "11110000",   -- ADD       s1, F0   ; s0=E0, C=1, Z=0 | ||||
|     16#09A# => brCall    & brC    & "0010001111", -- CALL      C, 08F   ; s0=04 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL Z" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#09B# => opSubC    & "0001" & "11100000",   -- SUB       s1, E0   ; s0=00, C=0, Z=1 | ||||
|     16#09C# => brCall    & brZ    & "0010001111", -- CALL      Z, 08F   ; s0=05 | ||||
|     16#09D# => opCompC   & "0000" & "00000101",   -- COMPARE   s0, 05 | ||||
|     16#09E# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 11) Test call return instructions | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#09F# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- define subroutines | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0A0# => brJump    & brDo   & "0010101101", -- JUMP      0AD | ||||
|                                                   -- _subRetNC_: | ||||
|     16#0A1# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0A2# => brRet     & brDo   & "----------", -- RETURN    NC | ||||
|     16#0A3# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _subRetNZ_: | ||||
|     16#0A4# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0A5# => brRet     & brDo   & "----------", -- RETURN    NZ | ||||
|     16#0A6# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _subRetC_: | ||||
|     16#0A7# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0A8# => brRet     & brDo   & "----------", -- RETURN    C | ||||
|     16#0A9# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _subRetZ_: | ||||
|     16#0AA# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0AB# => brRet     & brDo   & "----------", -- RETURN    Z | ||||
|     16#0AC# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN NC" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue6_: | ||||
|     16#0AD# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00   ; increment will give C=0, Z=0 | ||||
|     16#0AE# => brCall    & brNC   & "0010100001", -- CALL      NC, 0A1 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN NZ" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0AF# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00   ; increment will give C=0, Z=0 | ||||
|     16#0B0# => brCall    & brNZ   & "0010100100", -- CALL      NZ, 0A4 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN C" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0B1# => opLoadC   & "0000" & "11111111",   -- LOAD      s0, FF   ; increment will give C=1, Z=1 | ||||
|     16#0B2# => brCall    & brC    & "0010100111", -- CALL      C, 0A7 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN Z" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0B3# => opLoadC   & "0000" & "11111111",   -- LOAD      s0, FF   ; increment will give C=1, Z=1 | ||||
|     16#0B4# => brCall    & brZ    & "0010101010", -- CALL      Z, 0AA | ||||
|                                                   --=============================================================== | ||||
|                                                   -- End of tests | ||||
|                                                   -- | ||||
|                                                   -- The testbench should react if value 1 is written to address 00. | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0B5# => opLoadC   & "0000" & "00000001",   -- LOAD      s0, 01 | ||||
|     16#0B6# => opOutputC & "0000" & "00000000",   -- OUTPUT    s0, 00 | ||||
|     16#0B7# => brJump    & brDo   & "1111111111", -- JUMP      3FF | ||||
|                                                   --=============================================================== | ||||
|                                                   -- Assert error | ||||
|                                                   -- | ||||
|                                                   -- The testbench should react if value 0 is written to address 00. | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _error_: | ||||
|     16#3FD# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00 | ||||
|     16#3FE# => opOutputC & "0000" & "00000000",   -- OUTPUT    s0, 00 | ||||
|                                                   --=============================================================== | ||||
|                                                   -- End of instruction memory | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _endOfMemory_: | ||||
|     16#3FF# => brJump    & brDo   & "1111111111", -- JUMP      3FF | ||||
|     others => (others => '0') | ||||
|   ); | ||||
|  | ||||
| BEGIN | ||||
|  | ||||
|   process (clock) | ||||
|   begin | ||||
|     if rising_edge(clock) then | ||||
|       if en = '1' then | ||||
|         dataOut <= memoryArray(to_integer(address)); | ||||
|       end if; | ||||
|     end if; | ||||
|   end process; | ||||
|  | ||||
| END ARCHITECTURE mapped; | ||||
							
								
								
									
										24
									
								
								Libs/NanoBlaze/hdl/programCounter_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Libs/NanoBlaze/hdl/programCounter_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| ARCHITECTURE RTL OF programCounter IS | ||||
|  | ||||
|   signal pCounter: unsigned(progCounter'range); | ||||
|  | ||||
| BEGIN | ||||
|  | ||||
|   updateProgramCounter: process(reset, clock) | ||||
|   begin | ||||
|     if reset = '1' then | ||||
|       pCounter <= (others => '0'); | ||||
|     elsif rising_edge(clock) then | ||||
|       if incPC = '1' then | ||||
|         pCounter <= pCounter + 1; | ||||
|       elsif loadInstrAddress = '1' then | ||||
|         pCounter <= instrAddress; | ||||
|       elsif loadStoredPC = '1' then | ||||
|         pCounter <= storedProgCounter; | ||||
|       end if; | ||||
|     end if; | ||||
|   end process updateProgramCounter; | ||||
|  | ||||
|   progCounter <= pCounter; | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
							
								
								
									
										26
									
								
								Libs/NanoBlaze/hdl/registerFile_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Libs/NanoBlaze/hdl/registerFile_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| ARCHITECTURE RTL OF registerFile IS | ||||
|  | ||||
|   subtype registerType is signed(registersIn'range); | ||||
|   type registerArrayType is array (0 to 2**registerAddressBitNb-1) of registerType; | ||||
|   signal registerArray : registerArrayType; | ||||
|  | ||||
| BEGIN | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                            -- write to registers | ||||
|   updateRegister: process(reset, clock) | ||||
|   begin | ||||
|     if reset = '1' then | ||||
|       registerArray <= (others => (others => '0')); | ||||
|     elsif rising_edge(clock) then | ||||
|       if regWrite = '1' then | ||||
|         registerArray(to_integer(addrA)) <= registersIn; | ||||
|       end if; | ||||
|     end if; | ||||
|   end process updateRegister; | ||||
|  | ||||
|   ------------------------------------------------------------------------------ | ||||
|                                                           -- read from registers | ||||
|   opA <= registerArray(to_integer(addrA)); | ||||
|   opB <= registerArray(to_integer(addrB)); | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
							
								
								
									
										21
									
								
								Libs/NanoBlaze/hdl/rom_empty.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Libs/NanoBlaze/hdl/rom_empty.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| ARCHITECTURE empty OF programRom IS | ||||
|  | ||||
|   subtype memoryWordType is std_ulogic_vector(dataOut'range); | ||||
|   type memoryArrayType is array (0 to 2**address'length-1) of memoryWordType; | ||||
|  | ||||
|   signal memoryArray : memoryArrayType := ( | ||||
|     others => (others => '0') | ||||
|   ); | ||||
|  | ||||
| BEGIN | ||||
|  | ||||
|   process (clock) | ||||
|   begin | ||||
|     if rising_edge(clock) then | ||||
|       if en = '1' then | ||||
|         dataOut <= (others => '0'); | ||||
|       end if; | ||||
|     end if; | ||||
|   end process; | ||||
|  | ||||
| END ARCHITECTURE empty; | ||||
							
								
								
									
										431
									
								
								Libs/NanoBlaze/hdl/rom_mapped.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										431
									
								
								Libs/NanoBlaze/hdl/rom_mapped.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,431 @@ | ||||
| ARCHITECTURE mapped OF programRom IS | ||||
|  | ||||
|   subtype opCodeType is std_ulogic_vector(5 downto 0); | ||||
|   constant opLoadC   : opCodeType := "000000"; | ||||
|   constant opLoadR   : opCodeType := "000001"; | ||||
|   constant opInputC  : opCodeType := "000100"; | ||||
|   constant opInputR  : opCodeType := "000101"; | ||||
|   constant opFetchC  : opCodeType := "000110"; | ||||
|   constant opFetchR  : opCodeType := "000111"; | ||||
|   constant opAndC    : opCodeType := "001010"; | ||||
|   constant opAndR    : opCodeType := "001011"; | ||||
|   constant opOrC     : opCodeType := "001100"; | ||||
|   constant opOrR     : opCodeType := "001101"; | ||||
|   constant opXorC    : opCodeType := "001110"; | ||||
|   constant opXorR    : opCodeType := "001111"; | ||||
|   constant opTestC   : opCodeType := "010010"; | ||||
|   constant opTestR   : opCodeType := "010011"; | ||||
|   constant opCompC   : opCodeType := "010100"; | ||||
|   constant opCompR   : opCodeType := "010101"; | ||||
|   constant opAddC    : opCodeType := "011000"; | ||||
|   constant opAddR    : opCodeType := "011001"; | ||||
|   constant opAddCyC  : opCodeType := "011010"; | ||||
|   constant opAddCyR  : opCodeType := "011011"; | ||||
|   constant opSubC    : opCodeType := "011100"; | ||||
|   constant opSubR    : opCodeType := "011101"; | ||||
|   constant opSubCyC  : opCodeType := "011110"; | ||||
|   constant opSubCyR  : opCodeType := "011111"; | ||||
|   constant opShRot   : opCodeType := "100000"; | ||||
|   constant opOutputC : opCodeType := "101100"; | ||||
|   constant opOutputR : opCodeType := "101101"; | ||||
|   constant opStoreC  : opCodeType := "101110"; | ||||
|   constant opStoreR  : opCodeType := "101111"; | ||||
|  | ||||
|   subtype shRotCinType is std_ulogic_vector(2 downto 0); | ||||
|   constant shRotLdC : shRotCinType := "00-"; | ||||
|   constant shRotLdM : shRotCinType := "01-"; | ||||
|   constant shRotLdL : shRotCinType := "10-"; | ||||
|   constant shRotLd0 : shRotCinType := "110"; | ||||
|   constant shRotLd1 : shRotCinType := "111"; | ||||
|  | ||||
|   constant registerAddressBitNb : positive := 4; | ||||
|   constant shRotPadLength : positive | ||||
|     := dataOut'length - opCodeType'length - registerAddressBitNb | ||||
|      - 1 - shRotCinType'length; | ||||
|   subtype shRotDirType is std_ulogic_vector(1+shRotPadLength-1 downto 0); | ||||
|   constant shRotL : shRotDirType := (0 => '0', others => '-'); | ||||
|   constant shRotR : shRotDirType := (0 => '1', others => '-'); | ||||
|  | ||||
|   subtype branchCodeType is std_ulogic_vector(4 downto 0); | ||||
|   constant brRet  : branchCodeType := "10101"; | ||||
|   constant brCall : branchCodeType := "11000"; | ||||
|   constant brJump : branchCodeType := "11010"; | ||||
|   constant brReti : branchCodeType := "11100"; | ||||
|   constant brEni  : branchCodeType := "11110"; | ||||
|  | ||||
|   subtype branchConditionType is std_ulogic_vector(2 downto 0); | ||||
|   constant brDo : branchConditionType := "000"; | ||||
|   constant brZ  : branchConditionType := "100"; | ||||
|   constant brNZ : branchConditionType := "101"; | ||||
|   constant brC  : branchConditionType := "110"; | ||||
|   constant brNC : branchConditionType := "111"; | ||||
|  | ||||
|   subtype memoryWordType is std_ulogic_vector(dataOut'range); | ||||
|   type memoryArrayType is array (0 to 2**address'length-1) of memoryWordType; | ||||
|  | ||||
|   signal memoryArray : memoryArrayType := ( | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 1) Test logical operations with direct values | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#000# => opLoadC   & "0111" & "00000001",   -- LOAD      s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "LOAD", "AND" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#001# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#002# => opAndC    & "0000" & "00110011",   -- AND       s0, 33 | ||||
|     16#003# => opCompC   & "0000" & "00000011",   -- COMPARE   s0, 03 | ||||
|     16#004# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "OR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#005# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#006# => opOrC     & "0001" & "00110011",   -- OR        s1, 33 | ||||
|     16#007# => opCompC   & "0001" & "00111111",   -- COMPARE   s1, 3F | ||||
|     16#008# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "XOR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#009# => opLoadC   & "0010" & "00001111",   -- LOAD      s2, 0F | ||||
|     16#00A# => opXorC    & "0010" & "00110011",   -- XOR       s2, 33 | ||||
|     16#00B# => opCompC   & "0010" & "00111100",   -- COMPARE   s2, 3C | ||||
|     16#00C# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 2) Test logical operations with registers | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#00D# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "LOAD" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#00E# => opLoadC   & "0000" & "00110011",   -- LOAD      s0, 33 | ||||
|     16#00F# => opLoadR   & "0011" & "0000----",   -- LOAD      s3, s0 | ||||
|     16#010# => opCompC   & "0011" & "00110011",   -- COMPARE   s3, 33 | ||||
|     16#011# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "AND" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#012# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#013# => opAndR    & "0000" & "0011----",   -- AND       s0, s3 | ||||
|     16#014# => opCompC   & "0000" & "00000011",   -- COMPARE   s0, 03 | ||||
|     16#015# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "OR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#016# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#017# => opOrR     & "0001" & "0011----",   -- OR        s1, s3 | ||||
|     16#018# => opCompC   & "0001" & "00111111",   -- COMPARE   s1, 3F | ||||
|     16#019# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "XOR" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#01A# => opLoadC   & "0010" & "00001111",   -- LOAD      s2, 0F | ||||
|     16#01B# => opXorR    & "0010" & "0011----",   -- XOR       s2, s3 | ||||
|     16#01C# => opCompC   & "0010" & "00111100",   -- COMPARE   s2, 3C | ||||
|     16#01D# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 3) Test arithmetic operations with constants | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#01E# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "ADD" and "ADDCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#01F# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#020# => opAddC    & "0000" & "00110001",   -- ADD       s0, 31   ;  40 | ||||
|     16#021# => opAddCyC  & "0000" & "11110000",   -- ADDCY     s0, F0   ; 130 | ||||
|     16#022# => opAddCyC  & "0000" & "11110000",   -- ADDCY     s0, F0   ; 121 | ||||
|     16#023# => opAddC    & "0000" & "00001111",   -- ADD       s0, 0F   ;  30 | ||||
|     16#024# => opCompC   & "0000" & "00110000",   -- COMPARE   s0, 30 | ||||
|     16#025# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "SUB" and "SUBCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#026# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#027# => opSubC    & "0001" & "00001100",   -- SUB       s1, 0C   ;  03 | ||||
|     16#028# => opSubCyC  & "0001" & "11110000",   -- SUBCY     s1, F0   ; 113 | ||||
|     16#029# => opSubCyC  & "0001" & "11110000",   -- SUBCY     s1, F0   ;  22 | ||||
|     16#02A# => opSubC    & "0001" & "00000001",   -- SUB       s1, 01   ;  21 | ||||
|     16#02B# => opCompC   & "0001" & "00100001",   -- COMPARE   s1, 21 | ||||
|     16#02C# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 4) Test arithmetic operations with registers | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#02D# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "ADD" and "ADDCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#02E# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#02F# => opLoadC   & "0001" & "00110001",   -- LOAD      s1, 31 | ||||
|     16#030# => opLoadC   & "0010" & "11110000",   -- LOAD      s2, F0 | ||||
|     16#031# => opLoadC   & "0011" & "00001111",   -- LOAD      s3, 0F | ||||
|     16#032# => opAddR    & "0000" & "0001----",   -- ADD       s0, s1   ;  40 | ||||
|     16#033# => opAddCyR  & "0000" & "0010----",   -- ADDCY     s0, s2   ; 130 | ||||
|     16#034# => opAddCyR  & "0000" & "0010----",   -- ADDCY     s0, s2   ; 121 | ||||
|     16#035# => opAddR    & "0000" & "0011----",   -- ADD       s0, s3   ;  30 | ||||
|     16#036# => opCompC   & "0000" & "00110000",   -- COMPARE   s0, 30 | ||||
|     16#037# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "SUB" and "SUBCY" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#038# => opLoadC   & "0001" & "00001111",   -- LOAD      s1, 0F | ||||
|     16#039# => opLoadC   & "0000" & "00001100",   -- LOAD      s0, 0C | ||||
|     16#03A# => opLoadC   & "0010" & "11110000",   -- LOAD      s2, F0 | ||||
|     16#03B# => opLoadC   & "0011" & "00000001",   -- LOAD      s3, 01 | ||||
|     16#03C# => opSubR    & "0001" & "0000----",   -- SUB       s1, s0   ;  03 | ||||
|     16#03D# => opSubCyR  & "0001" & "0010----",   -- SUBCY     s1, s2   ; 113 | ||||
|     16#03E# => opSubCyR  & "0001" & "0010----",   -- SUBCY     s1, s2   ;  22 | ||||
|     16#03F# => opSubR    & "0001" & "0011----",   -- SUB       s1, s3   ;  21 | ||||
|     16#040# => opCompC   & "0001" & "00100001",   -- COMPARE   s1, 21 | ||||
|     16#041# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 5) Test shifts | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#042# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test shift right | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#043# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F   ; 0F | ||||
|     16#044# => opShRot   & "0000" & shRotR & shRotLd0,-- SR0       s0       ; 07 | ||||
|     16#045# => opShRot   & "0000" & shRotR & shRotLdM,-- SRX       s0       ; 03 | ||||
|     16#046# => opShRot   & "0000" & shRotR & shRotLd1,-- SR1       s0       ; 81 | ||||
|     16#047# => opShRot   & "0000" & shRotR & shRotLdM,-- SRX       s0       ; C0, C=1 | ||||
|     16#048# => opShRot   & "0000" & shRotR & shRotLdC,-- SRA       s0       ; E0, C=0 | ||||
|     16#049# => opShRot   & "0000" & shRotR & shRotLdC,-- SRA       s0       ; 70 | ||||
|     16#04A# => opCompC   & "0000" & "01110000",   -- COMPARE   s0, 70 | ||||
|     16#04B# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test shift left | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#04C# => opLoadC   & "0001" & "11110000",   -- LOAD      s1, F0   ; FO | ||||
|     16#04D# => opShRot   & "0001" & shRotL & shRotLd0,-- SL0       s1       ; E0 | ||||
|     16#04E# => opShRot   & "0001" & shRotL & shRotLdL,-- SLX       s1       ; C0 | ||||
|     16#04F# => opShRot   & "0001" & shRotL & shRotLd1,-- SL1       s1       ; 81 | ||||
|     16#050# => opShRot   & "0001" & shRotL & shRotLdL,-- SLX       s1       ; 03, C=1 | ||||
|     16#051# => opShRot   & "0001" & shRotL & shRotLdC,-- SLA       s1       ; 07, C=0 | ||||
|     16#052# => opShRot   & "0001" & shRotL & shRotLdC,-- SLA       s1       ; 0E | ||||
|     16#053# => opCompC   & "0001" & "00001110",   -- COMPARE   s1, 0E | ||||
|     16#054# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 6) Test comparison operators | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#055# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "COMPARE" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#056# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#057# => opCompC   & "0000" & "11110000",   -- COMPARE   s0, F0   ; A < B => C=1 | ||||
|     16#058# => brJump    & brNC   & "1111111101", -- JUMP      NC, 3FD | ||||
|     16#059# => opCompC   & "0000" & "11110000",   -- COMPARE   s0, F0   ; A < B => Z=0 | ||||
|     16#05A# => brJump    & brZ    & "1111111101", -- JUMP      Z, 3FD | ||||
|     16#05B# => opCompR   & "0000" & "0000----",   -- COMPARE   s0, s0   ; A = B => Z=1 | ||||
|     16#05C# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|     16#05D# => opCompC   & "0000" & "00001000",   -- COMPARE   s0, 08   ; A > B => C=0 | ||||
|     16#05E# => brJump    & brC    & "1111111101", -- JUMP      C, 3FD | ||||
|     16#05F# => opCompC   & "0000" & "00001000",   -- COMPARE   s0, 08   ; A > B => Z=0 | ||||
|     16#060# => brJump    & brZ    & "1111111101", -- JUMP      Z, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "TEST" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#061# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#062# => opTestC   & "0000" & "11110000",   -- TEST      s0, F0   ; AND is 00 => Z=1 | ||||
|     16#063# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|     16#064# => opTestC   & "0000" & "11111111",   -- TEST      s0, FF   ; AND is 0F => Z=0 | ||||
|     16#065# => brJump    & brZ    & "1111111101", -- JUMP      Z, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 7) Test INPUT and OUTPUT operators | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#066# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "INPUT" and "OUTPUT" direct | ||||
|                                                   -- | ||||
|                                                   -- The testbench should invert the word written at address FC. | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#067# => opLoadC   & "0000" & "10101010",   -- LOAD      s0, AA | ||||
|     16#068# => opOutputC & "0000" & "11111100",   -- OUTPUT    s0, FC | ||||
|     16#069# => opInputC  & "0001" & "11111100",   -- INPUT     s1, FC | ||||
|     16#06A# => opCompC   & "0001" & "01010101",   -- COMPARE   s1, 55 | ||||
|     16#06B# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "INPUT" and "OUTPUT" indexed | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#06C# => opLoadC   & "0000" & "11001100",   -- LOAD      s0, CC | ||||
|     16#06D# => opLoadC   & "0010" & "11111100",   -- LOAD      s2, FC | ||||
|     16#06E# => opOutputR & "0000" & "0010----",   -- OUTPUT    s0, (S2) | ||||
|     16#06F# => opInputR  & "0001" & "0010----",   -- INPUT     s1, (S2) | ||||
|     16#070# => opCompC   & "0001" & "00110011",   -- COMPARE   s1, 33 | ||||
|     16#071# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 8) Test STORE and FETCH operators | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#072# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "STORE" and "FETCH" direct | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#073# => opLoadC   & "0000" & "00001111",   -- LOAD      s0, 0F | ||||
|     16#074# => opStoreC  & "0000" & "00000011",   -- STORE     s0, 03 | ||||
|     16#075# => opFetchC  & "0001" & "00000011",   -- FETCH     s1, 03 | ||||
|     16#076# => opCompC   & "0001" & "00001111",   -- COMPARE   s1, 0F | ||||
|     16#077# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "STORE" and "FETCH" indexed | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#078# => opLoadC   & "0000" & "11110000",   -- LOAD      s0, F0 | ||||
|     16#079# => opLoadC   & "0010" & "00000100",   -- LOAD      s2, 04 | ||||
|     16#07A# => opStoreR  & "0000" & "0010----",   -- STORE     s0, (S2) | ||||
|     16#07B# => opFetchR  & "0001" & "0010----",   -- FETCH     s1, (S2) | ||||
|     16#07C# => opCompC   & "0001" & "11110000",   -- COMPARE   s1, F0 | ||||
|     16#07D# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 9) Test JUMP instructions | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#07E# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP NC" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#07F# => opLoadC   & "0000" & "11110000",   -- LOAD      s0, F0 | ||||
|     16#080# => opAddC    & "0000" & "00000000",   -- ADD       s0, 00   ; s0=F0, C=0, Z=0 | ||||
|     16#081# => brJump    & brNC   & "0010000011", -- JUMP      NC, 083 | ||||
|     16#082# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP NZ" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue1_: | ||||
|     16#083# => opAddC    & "0000" & "00000000",   -- ADD       s0, 00   ; s0=F0, C=0, Z=0 | ||||
|     16#084# => brJump    & brNZ   & "0010000110", -- JUMP      NZ, 086 | ||||
|     16#085# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP C" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue2_: | ||||
|     16#086# => opAddC    & "0000" & "11110000",   -- ADD       s0, F0   ; s0=E0, C=1, Z=0 | ||||
|     16#087# => brJump    & brC    & "0010001001", -- JUMP      C, 089 | ||||
|     16#088# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "JUMP Z" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue3_: | ||||
|     16#089# => opSubC    & "0000" & "11100000",   -- SUB       s0, E0   ; s0=00, C=0, Z=1 | ||||
|     16#08A# => brJump    & brZ    & "0010001100", -- JUMP      Z, 08C | ||||
|     16#08B# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _continue4_: | ||||
|     16#08C# => opLoadR   & "0000" & "0000----",   -- NOP | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 10) Test call instructions | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#08D# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- define subroutine | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#08E# => brJump    & brDo   & "0010010010", -- JUMP      092 | ||||
|                                                   -- _subRetDo_: | ||||
|     16#08F# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#090# => brRet     & brDo   & "----------", -- RETURN | ||||
|     16#091# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue5_: | ||||
|     16#092# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00 | ||||
|     16#093# => opLoadC   & "0001" & "11110000",   -- LOAD      s1, F0 | ||||
|     16#094# => brCall    & brDo   & "0010001111", -- CALL      08F      ; s0=01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL NC" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#095# => opAddC    & "0001" & "00000000",   -- ADD       s1, 00   ; s1=F0, C=0, Z=0 | ||||
|     16#096# => brCall    & brNC   & "0010001111", -- CALL      NC, 08F  ; s0=02 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL NZ" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#097# => opAddC    & "0001" & "00000000",   -- ADD       s1, 00   ; s1=F0, C=0, Z=0 | ||||
|     16#098# => brCall    & brNZ   & "0010001111", -- CALL      NZ, 08F  ; s0=03 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL C" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#099# => opAddC    & "0001" & "11110000",   -- ADD       s1, F0   ; s0=E0, C=1, Z=0 | ||||
|     16#09A# => brCall    & brC    & "0010001111", -- CALL      C, 08F   ; s0=04 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "CALL Z" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#09B# => opSubC    & "0001" & "11100000",   -- SUB       s1, E0   ; s0=00, C=0, Z=1 | ||||
|     16#09C# => brCall    & brZ    & "0010001111", -- CALL      Z, 08F   ; s0=05 | ||||
|     16#09D# => opCompC   & "0000" & "00000101",   -- COMPARE   s0, 05 | ||||
|     16#09E# => brJump    & brNZ   & "1111111101", -- JUMP      NZ, 3FD | ||||
|                                                   --=============================================================== | ||||
|                                                   -- 11) Test call return instructions | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#09F# => opAddC    & "0111" & "00000001",   -- ADD       s7, 01 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- define subroutines | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0A0# => brJump    & brDo   & "0010101101", -- JUMP      0AD | ||||
|                                                   -- _subRetNC_: | ||||
|     16#0A1# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0A2# => brRet     & brDo   & "----------", -- RETURN    NC | ||||
|     16#0A3# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _subRetNZ_: | ||||
|     16#0A4# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0A5# => brRet     & brDo   & "----------", -- RETURN    NZ | ||||
|     16#0A6# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _subRetC_: | ||||
|     16#0A7# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0A8# => brRet     & brDo   & "----------", -- RETURN    C | ||||
|     16#0A9# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   -- _subRetZ_: | ||||
|     16#0AA# => opAddC    & "0000" & "00000001",   -- ADD       s0, 01 | ||||
|     16#0AB# => brRet     & brDo   & "----------", -- RETURN    Z | ||||
|     16#0AC# => brJump    & brDo   & "1111111101", -- JUMP      3FD | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN NC" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _continue6_: | ||||
|     16#0AD# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00   ; increment will give C=0, Z=0 | ||||
|     16#0AE# => brCall    & brNC   & "0010100001", -- CALL      NC, 0A1 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN NZ" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0AF# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00   ; increment will give C=0, Z=0 | ||||
|     16#0B0# => brCall    & brNZ   & "0010100100", -- CALL      NZ, 0A4 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN C" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0B1# => opLoadC   & "0000" & "11111111",   -- LOAD      s0, FF   ; increment will give C=1, Z=1 | ||||
|     16#0B2# => brCall    & brC    & "0010100111", -- CALL      C, 0A7 | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- Test "RETURN Z" | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0B3# => opLoadC   & "0000" & "11111111",   -- LOAD      s0, FF   ; increment will give C=1, Z=1 | ||||
|     16#0B4# => brCall    & brZ    & "0010101010", -- CALL      Z, 0AA | ||||
|                                                   --=============================================================== | ||||
|                                                   -- End of tests | ||||
|                                                   -- | ||||
|                                                   -- The testbench should react if value 1 is written to address 00. | ||||
|                                                   ----------------------------------------------------------------- | ||||
|     16#0B5# => opLoadC   & "0000" & "00000001",   -- LOAD      s0, 01 | ||||
|     16#0B6# => opOutputC & "0000" & "00000000",   -- OUTPUT    s0, 00 | ||||
|     16#0B7# => brJump    & brDo   & "1111111111", -- JUMP      3FF | ||||
|                                                   --=============================================================== | ||||
|                                                   -- Assert error | ||||
|                                                   -- | ||||
|                                                   -- The testbench should react if value 0 is written to address 00. | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _error_: | ||||
|     16#3FD# => opLoadC   & "0000" & "00000000",   -- LOAD      s0, 00 | ||||
|     16#3FE# => opOutputC & "0000" & "00000000",   -- OUTPUT    s0, 00 | ||||
|                                                   --=============================================================== | ||||
|                                                   -- End of instruction memory | ||||
|                                                   ----------------------------------------------------------------- | ||||
|                                                   -- _endOfMemory_: | ||||
|     16#3FF# => brJump    & brDo   & "1111111111", -- JUMP      3FF | ||||
|     others => (others => '0') | ||||
|   ); | ||||
|  | ||||
| BEGIN | ||||
|  | ||||
|   process (clock) | ||||
|   begin | ||||
|     if rising_edge(clock) then | ||||
|       if en = '1' then | ||||
|         dataOut <= memoryArray(to_integer(address)); | ||||
|       end if; | ||||
|     end if; | ||||
|   end process; | ||||
|  | ||||
| END ARCHITECTURE mapped; | ||||
							
								
								
									
										21
									
								
								Libs/NanoBlaze/hdl/scratchpad_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Libs/NanoBlaze/hdl/scratchpad_RTL.vhd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| ARCHITECTURE RTL OF scratchpad IS | ||||
|  | ||||
|   subtype memoryWordType is signed(dataOut'range); | ||||
|   type memoryArrayType is array (0 to 2**addr'length-1) of memoryWordType; | ||||
|  | ||||
|   signal memoryArray : memoryArrayType; | ||||
|  | ||||
| BEGIN | ||||
|  | ||||
|   process (clock) | ||||
|   begin | ||||
|     if rising_edge(clock) then | ||||
|       if write = '1' then | ||||
|         memoryArray(to_integer(addr)) <= dataIn; | ||||
|       end if; | ||||
|     end if; | ||||
|   end process; | ||||
|  | ||||
|   dataOut <= memoryArray(to_integer(addr)); | ||||
|  | ||||
| END ARCHITECTURE RTL; | ||||
		Reference in New Issue
	
	Block a user