Archived
1
0

Initial commit

This commit is contained in:
github-classroom[bot]
2024-02-23 13:01:05 +00:00
committed by GitHub
commit d212040c30
1914 changed files with 1290006 additions and 0 deletions

View 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;

View 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;

View 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;

View 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;

View 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;

View 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";
}

File diff suppressed because it is too large Load Diff

View 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

View 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.

View 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;

View 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;

View 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;

View 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;

View 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;

View 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;

View File

@ -0,0 +1,4 @@
INCLUDE list {
DEFAULT atom 1
}
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1,4 @@
INCLUDE list {
DEFAULT atom 1
}
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1,4 @@
INCLUDE list {
DEFAULT atom 1
}
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1,4 @@
INCLUDE list {
DEFAULT atom 1
}
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1,4 @@
INCLUDE list {
DEFAULT atom 1
}
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1,4 @@
INCLUDE list {
DEFAULT atom 1
}
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1,4 @@
INCLUDE list {
DEFAULT atom 1
}
DIALECT atom VHDL_2008

View File

@ -0,0 +1 @@
DIALECT atom VHDL_2008

View File

@ -0,0 +1,2 @@
DEFAULT_FILE atom alu_RTL.vhd
DEFAULT_ARCHITECTURE atom RTL

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom struct
DEFAULT_FILE atom alu@and@regs/struct.bd

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom RTL
DEFAULT_FILE atom aluBOpSelector_RTL.vhd

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom RTL
DEFAULT_FILE atom branchStack_RTL.vhd

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom RTL
DEFAULT_FILE atom controller_RTL.vhd

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom RTL
DEFAULT_FILE atom instructionDecoder_RTL.vhd

View File

@ -0,0 +1,3 @@
DEFAULT_FILE atom nano@blaze/struct.bd
DEFAULT_ARCHITECTURE atom struct
TOP_MARKER atom 1

View File

@ -0,0 +1,2 @@
DEFAULT_FILE atom nano@processor/struct.bd
DEFAULT_ARCHITECTURE atom struct

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom RTL
DEFAULT_FILE atom programCounter_RTL.vhd

View File

@ -0,0 +1,2 @@
DEFAULT_FILE atom rom_mapped.vhd
DEFAULT_ARCHITECTURE atom mapped

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom RTL
DEFAULT_FILE atom registerFile_RTL.vhd

View File

@ -0,0 +1,2 @@
DEFAULT_ARCHITECTURE atom RTL
DEFAULT_FILE atom scratchpad_RTL.vhd

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff