FIX: fixes and ADD: small assembler
This commit is contained in:
parent
bc07966401
commit
a53abe0ff9
12
asm/mult.s
Normal file
12
asm/mult.s
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
lui $1, 5
|
||||||
|
lui $2, 6
|
||||||
|
lui $3, 0
|
||||||
|
lui $4, 1
|
||||||
|
add $5, $0, $2
|
||||||
|
loop:
|
||||||
|
add $3, $3, $1
|
||||||
|
sub $5, $5, $4
|
||||||
|
jpz end
|
||||||
|
jmp loop
|
||||||
|
end:
|
||||||
|
hlt
|
375
scripts/asm.pl
Executable file
375
scripts/asm.pl
Executable file
@ -0,0 +1,375 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
#
|
||||||
|
# Small assembler for the Simple Processor Core
|
||||||
|
#
|
||||||
|
|
||||||
|
my $nr_instr_bytes = 4;
|
||||||
|
my $nr_opcode_bits = 6;
|
||||||
|
my $nr_reg_bits = 5;
|
||||||
|
my $startaddr = 0;
|
||||||
|
|
||||||
|
# mnemonnic to opcode conversion
|
||||||
|
my %opcodes = (
|
||||||
|
'shl' => 0x00,
|
||||||
|
'shr' => 0x01,
|
||||||
|
'sto' => 0x02,
|
||||||
|
'loa' => 0x03,
|
||||||
|
'add' => 0x04,
|
||||||
|
'sub' => 0x05,
|
||||||
|
'addc' => 0x06,
|
||||||
|
'subc' => 0x07,
|
||||||
|
'or' => 0x08,
|
||||||
|
'and' => 0x09,
|
||||||
|
'xor' => 0x0A,
|
||||||
|
'not' => 0x0B,
|
||||||
|
'jpz' => 0x0C,
|
||||||
|
'jpc' => 0x0D,
|
||||||
|
'jmp' => 0x0E,
|
||||||
|
'lui' => 0x0F,
|
||||||
|
'hlt' => 0x3F
|
||||||
|
);
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
# main program
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
my $filename = $ARGV[0];
|
||||||
|
|
||||||
|
my %labels;
|
||||||
|
|
||||||
|
# check if file exists
|
||||||
|
if ( !-e $filename ) {
|
||||||
|
die("file does not exist\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
open my $src, "<" . $filename;
|
||||||
|
|
||||||
|
my $addr = $startaddr;
|
||||||
|
my $lines = 0;
|
||||||
|
|
||||||
|
my @instructions;
|
||||||
|
my $valid;
|
||||||
|
|
||||||
|
while ( my $line = <$src> ) {
|
||||||
|
|
||||||
|
$line =~ /^(\S+)\s(.*)$/;
|
||||||
|
my $INSTR = $1;
|
||||||
|
my $REST = $2;
|
||||||
|
|
||||||
|
$addr++;
|
||||||
|
$lines++;
|
||||||
|
my $opc = $opcodes{"$INSTR"};
|
||||||
|
my $label = "";
|
||||||
|
$opc = $opc << 26;
|
||||||
|
$valid = 1;
|
||||||
|
|
||||||
|
if ( $INSTR eq "shl" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for shl in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "shr" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for shr in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "sto" ) {
|
||||||
|
if ( $REST =~ /^\$(.*),(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 16;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
my $imm = $2;
|
||||||
|
$imm =~ s/\s//g;
|
||||||
|
|
||||||
|
$opc = $opc | $imm;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for sto in line $lines\n")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "loa" ) {
|
||||||
|
if ( $REST =~ /^\$(.*),(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
my $imm = $2;
|
||||||
|
$imm =~ s/\s//g;
|
||||||
|
|
||||||
|
$opc = $opc | $imm;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for sto in line $lines\n")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "add" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for add in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "sub" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for sub in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "addc" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for addc in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "subc" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for subc in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "or" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for or in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "and" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for and in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "xor" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*),[\s\$]+(.*),[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
my $op1 = $2;
|
||||||
|
my $op2 = $3;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
$op1 =~ s/\s//g;
|
||||||
|
$op1 = $op1 << 16;
|
||||||
|
$opc = $opc | $op1;
|
||||||
|
|
||||||
|
$op2 =~ s/\s//g;
|
||||||
|
$op2 = $op2 << 11;
|
||||||
|
$opc = $opc | $op2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for xor in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "not" ) {
|
||||||
|
if ( $REST =~ /^[\s\$]+(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for add in line $lines\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "jpz" ) {
|
||||||
|
$label = $REST;
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "jpc" ) {
|
||||||
|
$label = $REST;
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "jmp" ) {
|
||||||
|
$label = $REST;
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "hlt" ) {
|
||||||
|
}
|
||||||
|
elsif ( $INSTR eq "lui" ) {
|
||||||
|
if ( $REST =~ /^\$(.*),(.*)$/ ) {
|
||||||
|
my $dst = $1;
|
||||||
|
$dst =~ s/\s//g;
|
||||||
|
$dst = $dst << 21;
|
||||||
|
$opc = $opc | $dst;
|
||||||
|
|
||||||
|
my $imm = $2;
|
||||||
|
$imm =~ s/\s//g;
|
||||||
|
|
||||||
|
$opc = $opc | $imm;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("ASM: wrong number of parameters for lui in line $lines\n")
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elsif ( $INSTR =~ /^(.*):$/ ) {
|
||||||
|
$labels{$1} = $addr;
|
||||||
|
$addr--;
|
||||||
|
$valid = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$addr--;
|
||||||
|
$valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $valid == 1 ) {
|
||||||
|
$line =~ s/\n//;
|
||||||
|
|
||||||
|
my $instruction = {};
|
||||||
|
|
||||||
|
$instruction->{addr} = $addr;
|
||||||
|
$instruction->{opc} = $opc;
|
||||||
|
$instruction->{comment} = $line;
|
||||||
|
$instruction->{label} = $label;
|
||||||
|
|
||||||
|
push( @instructions, $instruction );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close $src;
|
||||||
|
|
||||||
|
# correct labels
|
||||||
|
for my $i (@instructions) {
|
||||||
|
if ( $i->{label} =~ /\S+/ ) {
|
||||||
|
for my $l ( keys %labels ) {
|
||||||
|
|
||||||
|
if ( $i->{label} eq $l ) {
|
||||||
|
$i->{opc} = $i->{opc} | $labels{$l};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for my $i (@instructions) {
|
||||||
|
if ($ARGV[1] eq "-vhdl") {
|
||||||
|
printf("%4s \t => B\"%.32b\", --%s\n ",$i->{addr}, $i->{opc}, $i->{comment});
|
||||||
|
} else {
|
||||||
|
printf( "%4s %.32b #%s\n", $i->{addr}, $i->{opc}, $i->{comment} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
33
src/CPU.vhd
33
src/CPU.vhd
@ -66,13 +66,20 @@ architecture Behavioral of CPU is
|
|||||||
iClk : in std_logic;
|
iClk : in std_logic;
|
||||||
iReset : in std_logic;
|
iReset : in std_logic;
|
||||||
|
|
||||||
|
icRegAsel : in std_logic_vector(4 downto 0);
|
||||||
|
icRegBsel : in std_logic_vector(4 downto 0);
|
||||||
|
odRegA : out DATA;
|
||||||
|
odRegB : out DATA;
|
||||||
|
|
||||||
|
|
||||||
|
icRegINsel : in std_logic_vector(4 downto 0);
|
||||||
|
|
||||||
idDataIn : in DATA;
|
idDataIn : in DATA;
|
||||||
idCarryIn : in std_logic;
|
idCarryIn : in std_logic;
|
||||||
idZeroIn : in std_logic;
|
idZeroIn : in std_logic;
|
||||||
|
|
||||||
icLoadEn : in std_logic;
|
icLoadEn : in std_logic;
|
||||||
|
|
||||||
odDataOut : out DATA;
|
|
||||||
odCarryOut : out std_logic;
|
odCarryOut : out std_logic;
|
||||||
odZeroOut : out std_logic
|
odZeroOut : out std_logic
|
||||||
);
|
);
|
||||||
@ -106,6 +113,9 @@ architecture Behavioral of CPU is
|
|||||||
|
|
||||||
odAddress : out ADDRESS;
|
odAddress : out ADDRESS;
|
||||||
odImmidiate : out DATA;
|
odImmidiate : out DATA;
|
||||||
|
odRegAsel : out std_logic_vector(4 downto 0);
|
||||||
|
odRegBsel : out std_logic_vector(4 downto 0);
|
||||||
|
odRegINsel : out std_logic_vector(4 downto 0);
|
||||||
ocOperation : out OPTYPE
|
ocOperation : out OPTYPE
|
||||||
);
|
);
|
||||||
end component;
|
end component;
|
||||||
@ -142,6 +152,11 @@ architecture Behavioral of CPU is
|
|||||||
signal sdDataIn : DATA;
|
signal sdDataIn : DATA;
|
||||||
signal sdAddress : ADDRESS;
|
signal sdAddress : ADDRESS;
|
||||||
signal sdImmidiate : DATA;
|
signal sdImmidiate : DATA;
|
||||||
|
signal sdRegAsel : std_logic_vector(4 downto 0);
|
||||||
|
signal sdRegBsel : std_logic_vector(4 downto 0);
|
||||||
|
signal sdRegINsel : std_logic_vector(4 downto 0);
|
||||||
|
signal sdRegA : DATA;
|
||||||
|
signal sdRegB : DATA;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@ -164,20 +179,25 @@ begin
|
|||||||
iClk => iClk,
|
iClk => iClk,
|
||||||
iReset => iReset,
|
iReset => iReset,
|
||||||
|
|
||||||
|
icRegAsel => sdRegAsel,
|
||||||
|
icRegBsel => sdRegBsel,
|
||||||
|
icRegINsel => sdRegINsel,
|
||||||
|
|
||||||
idDataIn => sdAkkuRes,
|
idDataIn => sdAkkuRes,
|
||||||
idCarryIn => sdCarryAkku,
|
idCarryIn => sdCarryAkku,
|
||||||
idZeroIn => sdZeroAkku,
|
idZeroIn => sdZeroAkku,
|
||||||
|
|
||||||
icLoadEn => scLoadEn,
|
icLoadEn => scLoadEn,
|
||||||
|
|
||||||
odDataOut => sdDataOut,
|
odRegA => sdRegA,
|
||||||
|
odRegB => sdRegB,
|
||||||
odCarryOut => sdCarryRF,
|
odCarryOut => sdCarryRF,
|
||||||
odZeroOut => sdZeroRF
|
odZeroOut => sdZeroRF
|
||||||
);
|
);
|
||||||
|
|
||||||
Calc : ALU Port MAP(
|
Calc : ALU Port MAP(
|
||||||
idOperand1 => sdDataOut,
|
idOperand1 => sdRegA,
|
||||||
idOperand2 => sdDataIn,
|
idOperand2 => sdRegB,
|
||||||
idImmidiate => sdImmidiate,
|
idImmidiate => sdImmidiate,
|
||||||
idCarryIn => sdCarryRF,
|
idCarryIn => sdCarryRF,
|
||||||
|
|
||||||
@ -200,6 +220,9 @@ begin
|
|||||||
|
|
||||||
odAddress => sdAddress,
|
odAddress => sdAddress,
|
||||||
odImmidiate => sdImmidiate,
|
odImmidiate => sdImmidiate,
|
||||||
|
odRegAsel => sdRegAsel,
|
||||||
|
odRegBsel => sdRegBsel,
|
||||||
|
odRegINsel => sdRegINsel,
|
||||||
ocOperation => scOpCode
|
ocOperation => scOpCode
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -212,7 +235,7 @@ begin
|
|||||||
icBusCtrlCPU => scRnotWRam,
|
icBusCtrlCPU => scRnotWRam,
|
||||||
icRAMEnable => scEnableRAM,
|
icRAMEnable => scEnableRAM,
|
||||||
odDataOutCPU => sdDataIn,
|
odDataOutCPU => sdDataIn,
|
||||||
idDataInCPU => sdDataOut,
|
idDataInCPU => sdRegA,
|
||||||
idAddressCPU => sdAddress
|
idAddressCPU => sdAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -46,7 +46,11 @@ entity FetchDecode is
|
|||||||
|
|
||||||
odAddress : out ADDRESS;
|
odAddress : out ADDRESS;
|
||||||
odImmidiate : out DATA;
|
odImmidiate : out DATA;
|
||||||
|
odRegAsel : out std_logic_vector(4 downto 0);
|
||||||
|
odRegBsel : out std_logic_vector(4 downto 0);
|
||||||
|
odRegINsel : out std_logic_vector(4 downto 0);
|
||||||
ocOperation : out OPTYPE
|
ocOperation : out OPTYPE
|
||||||
|
|
||||||
);
|
);
|
||||||
end FetchDecode;
|
end FetchDecode;
|
||||||
|
|
||||||
@ -55,10 +59,14 @@ architecture Behavioral of FetchDecode is
|
|||||||
signal sdAdr, sdAdr_next : ADDRESS;
|
signal sdAdr, sdAdr_next : ADDRESS;
|
||||||
signal sdImmidate, sdImmidiate_next : DATA;
|
signal sdImmidate, sdImmidiate_next : DATA;
|
||||||
|
|
||||||
|
signal sdRegAsel, sdRegAsel_next : std_logic_vector(4 downto 0);
|
||||||
|
signal sdRegBsel, sdRegBsel_next : std_logic_vector(4 downto 0);
|
||||||
|
signal sdRegINsel, sdRegINsel_next : std_logic_vector(4 downto 0);
|
||||||
|
|
||||||
signal scOp, scOp_next : OPTYPE;
|
signal scOp, scOp_next : OPTYPE;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Transition: process(idData, sdImmidate, icLoadInstr, icJump, icNextPC, sdAdr, sdPC, scOp)
|
Transition: process(idData, sdImmidate, icLoadInstr, icJump, icNextPC, sdAdr, sdPC, scOp, sdRegAsel, sdRegBsel, sdRegINsel)
|
||||||
begin
|
begin
|
||||||
-- defaults
|
-- defaults
|
||||||
sdAdr_next <= sdAdr;
|
sdAdr_next <= sdAdr;
|
||||||
@ -66,10 +74,17 @@ begin
|
|||||||
scOp_next <= scOp;
|
scOp_next <= scOp;
|
||||||
sdImmidiate_next <= sdImmidate;
|
sdImmidiate_next <= sdImmidate;
|
||||||
|
|
||||||
|
sdRegAsel_next <= sdRegAsel;
|
||||||
|
sdRegBsel_next <= sdRegBsel;
|
||||||
|
sdRegINsel_next <= sdRegINsel;
|
||||||
|
|
||||||
--! ISA Definition
|
--! ISA Definition
|
||||||
if (icLoadInstr = '1') then
|
if (icLoadInstr = '1') then
|
||||||
sdAdr_next <= idData(15 downto 0);
|
sdAdr_next <= "0000" & idData(11 downto 0);
|
||||||
sdImmidiate_next <= "0000000000000000" & idData(15 downto 0);
|
sdImmidiate_next <= "0000000000000000" & idData(15 downto 0);
|
||||||
|
sdRegINsel_next <= idData(25 downto 21);
|
||||||
|
sdRegAsel_next <= idData(20 downto 16);
|
||||||
|
sdRegBsel_next <= idData(15 downto 11);
|
||||||
|
|
||||||
case idData(31 downto 26) is
|
case idData(31 downto 26) is
|
||||||
when "000000" => scOp_next <= shl;
|
when "000000" => scOp_next <= shl;
|
||||||
@ -111,6 +126,10 @@ begin
|
|||||||
sdPC <= (others => '0');
|
sdPC <= (others => '0');
|
||||||
sdAdr <= (others => '0');
|
sdAdr <= (others => '0');
|
||||||
sdImmidate <= (others=>'0');
|
sdImmidate <= (others=>'0');
|
||||||
|
sdRegAsel <= (others=>'0');
|
||||||
|
sdRegBsel <= (others=>'0');
|
||||||
|
sdRegINsel <= (others=>'0');
|
||||||
|
|
||||||
scOp <= hlt;
|
scOp <= hlt;
|
||||||
|
|
||||||
elsif (rising_edge(iClk)) then
|
elsif (rising_edge(iClk)) then
|
||||||
@ -118,6 +137,9 @@ begin
|
|||||||
sdAdr <= sdAdr_next;
|
sdAdr <= sdAdr_next;
|
||||||
scOp <= scOp_next;
|
scOp <= scOp_next;
|
||||||
sdImmidate <= sdImmidiate_next;
|
sdImmidate <= sdImmidiate_next;
|
||||||
|
sdRegAsel <= sdRegAsel_next;
|
||||||
|
sdRegBsel <= sdRegBsel_next;
|
||||||
|
sdRegINsel <= sdRegINsel_next;
|
||||||
end if;
|
end if;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
@ -131,5 +153,11 @@ begin
|
|||||||
scOp_next;
|
scOp_next;
|
||||||
|
|
||||||
odImmidiate <= sdImmidate when icLoadInstr = '0' else sdImmidiate_next;
|
odImmidiate <= sdImmidate when icLoadInstr = '0' else sdImmidiate_next;
|
||||||
|
|
||||||
|
odRegAsel <= sdRegAsel when icLoadInstr = '0' else sdRegAsel_next;
|
||||||
|
odRegBsel <= sdRegBsel when icLoadInstr = '0' else sdRegBsel_next;
|
||||||
|
odRegINsel <= sdRegINsel when icLoadInstr = '0' else sdRegINsel_next;
|
||||||
|
|
||||||
|
|
||||||
end Behavioral;
|
end Behavioral;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ architecture Behavioral of MemInterface is
|
|||||||
begin
|
begin
|
||||||
|
|
||||||
ocRnotW <= icBusCtrlCPU;
|
ocRnotW <= icBusCtrlCPU;
|
||||||
odAddress <= idAddressCPU;
|
odAddress <= idAddressCPU when icRAMEnable='1' else (others=>'0');
|
||||||
ocEnable <= icRAMEnable;
|
ocEnable <= icRAMEnable;
|
||||||
|
|
||||||
odDataOutCPU <= bdDataBus;
|
odDataOutCPU <= bdDataBus;
|
||||||
|
27
src/RAM.vhd
27
src/RAM.vhd
@ -34,22 +34,17 @@ architecture arch of RAM is
|
|||||||
type MEMORY is ARRAY(0 to 255) of DATA; --! array of data words
|
type MEMORY is ARRAY(0 to 255) of DATA; --! array of data words
|
||||||
|
|
||||||
constant Prog1 : MEMORY := ( --! 4k * 32bit of RAM
|
constant Prog1 : MEMORY := ( --! 4k * 32bit of RAM
|
||||||
0 => B"001111_000_000_000_0_0000000000000101", -- li 5
|
1 => B"00111100001000000000000000000101", --lui $1, 5
|
||||||
1 => B"000010_000_000_000_0_0000000000100000", -- sto 32
|
2 => B"00111100010000000000000000000110", --lui $2, 6
|
||||||
2 => B"111111_000_000_000_0_0000000000000000", -- hlt
|
3 => B"00111100011000000000000000000000", --lui $3, 0
|
||||||
-- 0 => B"0011_000000001010", -- loa 10 (n)
|
4 => B"00111100100000000000000000000001", --lui $4, 1
|
||||||
-- 1 => B"1100_000000001000", -- jpz 8
|
5 => B"00010000101000000001000000000000", --add $5, $0, $2
|
||||||
-- 2 => B"0101_000000001100", -- sub <1>
|
6 => B"00010000011000110000100000000000", --add $3, $3, $1
|
||||||
-- 3 => B"0010_000000001010", -- sto 10 (n)
|
7 => B"00010100101001010010000000000000", --sub $5, $5, $4
|
||||||
-- 4 => B"0011_000000001011", -- loa 11 (a)
|
8 => B"00110000000000000000000000001010", --jpz end
|
||||||
-- 5 => B"0100_000000001001", -- add <result>
|
9 => B"00111000000000000000000000000110", --jmp loop
|
||||||
-- 6 => B"0010_000000001001", -- sto <result>
|
10 => B"11111100000000000000000000000000", --hlt
|
||||||
-- 7 => B"1110_000000000000", -- jmp 0
|
|
||||||
-- 8 => B"1111_000000000000", -- hlt
|
|
||||||
-- 9 => B"0000_000000000000", -- result
|
|
||||||
-- 10 => B"0000_000000000011", -- n=3
|
|
||||||
-- 11 => B"0000_000000000101", -- a=1
|
|
||||||
-- 12 => B"0000_000000000001", -- 1
|
|
||||||
|
|
||||||
|
|
||||||
others => (others => '0')
|
others => (others => '0')
|
||||||
|
@ -22,49 +22,61 @@ use IEEE.STD_LOGIC_1164.ALL;
|
|||||||
|
|
||||||
library work;
|
library work;
|
||||||
use work.cpupkg.all;
|
use work.cpupkg.all;
|
||||||
-- Uncomment the following library declaration if using
|
use ieee.numeric_std.all;
|
||||||
-- arithmetic functions with Signed or Unsigned values
|
|
||||||
--use IEEE.NUMERIC_STD.ALL;
|
|
||||||
|
|
||||||
-- Uncomment the following library declaration if instantiating
|
|
||||||
-- any Xilinx primitives in this code.
|
|
||||||
--library UNISIM;
|
|
||||||
--use UNISIM.VComponents.all;
|
|
||||||
|
|
||||||
entity RegFile is
|
entity RegFile is
|
||||||
Port(
|
Port(
|
||||||
iClk : in std_logic;
|
iClk : in std_logic;
|
||||||
iReset : in std_logic;
|
iReset : in std_logic;
|
||||||
|
|
||||||
|
icRegAsel : in std_logic_vector(4 downto 0);
|
||||||
|
icRegBsel : in std_logic_vector(4 downto 0);
|
||||||
|
odRegA : out DATA;
|
||||||
|
odRegB : out DATA;
|
||||||
|
|
||||||
|
|
||||||
|
icRegINsel : in std_logic_vector(4 downto 0);
|
||||||
|
|
||||||
idDataIn : in DATA;
|
idDataIn : in DATA;
|
||||||
idCarryIn : in std_logic;
|
idCarryIn : in std_logic;
|
||||||
idZeroIn : in std_logic;
|
idZeroIn : in std_logic;
|
||||||
|
|
||||||
icLoadEn : in std_logic;
|
icLoadEn : in std_logic;
|
||||||
|
|
||||||
odDataOut : out DATA;
|
|
||||||
odCarryOut : out std_logic;
|
odCarryOut : out std_logic;
|
||||||
odZeroOut : out std_logic
|
odZeroOut : out std_logic
|
||||||
);
|
);
|
||||||
end RegFile;
|
end RegFile;
|
||||||
|
|
||||||
architecture Behavioral of RegFile is
|
architecture Behavioral of RegFile is
|
||||||
|
|
||||||
|
type registerFileType is array (0 to 31) of DATA;
|
||||||
|
signal registerFile : registerFileType;
|
||||||
|
|
||||||
signal sdData : DATA;
|
signal sdData : DATA;
|
||||||
signal sdCarry : std_logic;
|
signal sdCarry : std_logic;
|
||||||
signal sdZero : std_logic;
|
signal sdZero : std_logic;
|
||||||
begin
|
begin
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Execute Transition
|
-- Execute Transition
|
||||||
process(iClk, iReset)
|
process(iClk, iReset)
|
||||||
begin
|
begin
|
||||||
if (iReset = '1') then
|
if (iReset = '1') then
|
||||||
sdData <= (others => '0');
|
for i in 31 downto 0 loop
|
||||||
|
registerFile(i) <= (others=>'0');
|
||||||
|
end loop;
|
||||||
|
|
||||||
sdCarry <= '0';
|
sdCarry <= '0';
|
||||||
sdZero <= '0';
|
sdZero <= '0';
|
||||||
|
|
||||||
elsif (rising_edge(iClk)) then
|
elsif (rising_edge(iClk)) then
|
||||||
if (icLoadEn = '1') then
|
if (icLoadEn = '1') then
|
||||||
sdData <= idDataIn;
|
registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn;
|
||||||
sdCarry <= idCarryIn;
|
sdCarry <= idCarryIn;
|
||||||
sdZero <= idZeroIn;
|
sdZero <= idZeroIn;
|
||||||
|
|
||||||
@ -74,8 +86,9 @@ begin
|
|||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
-- Output
|
|
||||||
odDataOut <= sdData;
|
odRegA <= registerFile(to_integer(unsigned(icRegAsel)));
|
||||||
|
odRegB <= registerFile(to_integer(unsigned(icRegBsel)));
|
||||||
odCarryOut <= sdCarry;
|
odCarryOut <= sdCarry;
|
||||||
odZeroOut <= sdZero;
|
odZeroOut <= sdZero;
|
||||||
|
|
||||||
|
@ -113,14 +113,14 @@ begin
|
|||||||
when decode =>
|
when decode =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '1'; -- read from RAM
|
||||||
ocLoadEn <= '0'; -- do not save result
|
ocLoadEn <= '0'; -- do not save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '1'; -- load instruction
|
ocLoadInstr <= '1'; -- load instruction
|
||||||
ocNextPC <= '1'; -- do not increment pc
|
ocNextPC <= '1'; -- do not increment pc
|
||||||
ocAddrSel <= '0'; -- pc on addressbus
|
ocAddrSel <= '0'; -- pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exshl =>
|
when exshl =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
@ -129,7 +129,7 @@ begin
|
|||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exshr =>
|
when exshr =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
@ -165,79 +165,79 @@ begin
|
|||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exadd =>
|
when exadd =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exsub =>
|
when exsub =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exaddc =>
|
when exaddc =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exsubc =>
|
when exsubc =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exopor =>
|
when exopor =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exopand =>
|
when exopand =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exopxor =>
|
when exopxor =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exopnot =>
|
when exopnot =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '1'; -- save result
|
ocLoadEn <= '1'; -- save result
|
||||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
ocNextPC <= '0'; -- increment pc
|
ocNextPC <= '0'; -- increment pc
|
||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '0'; -- no ocJump
|
ocJump <= '0'; -- no ocJump
|
||||||
|
|
||||||
when exjpz =>
|
when exjpz =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '0'; -- save result
|
ocLoadEn <= '0'; -- save result
|
||||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
@ -246,7 +246,7 @@ begin
|
|||||||
ocJump <= '1'; -- ocJump
|
ocJump <= '1'; -- ocJump
|
||||||
|
|
||||||
when exjpc =>
|
when exjpc =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '0'; -- save result
|
ocLoadEn <= '0'; -- save result
|
||||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
@ -255,7 +255,7 @@ begin
|
|||||||
ocJump <= '1'; -- ocJump
|
ocJump <= '1'; -- ocJump
|
||||||
|
|
||||||
when exjmp =>
|
when exjmp =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '0'; -- save result
|
ocLoadEn <= '0'; -- save result
|
||||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
@ -263,7 +263,7 @@ begin
|
|||||||
ocAddrSel <= '0'; -- no pc on addressbus
|
ocAddrSel <= '0'; -- no pc on addressbus
|
||||||
ocJump <= '1'; -- ocJump
|
ocJump <= '1'; -- ocJump
|
||||||
when exhlt =>
|
when exhlt =>
|
||||||
ocRnotWRam <= '1'; -- read from RAM
|
ocRnotWRam <= '0'; -- read from RAM
|
||||||
ocLoadEn <= '0'; -- save result
|
ocLoadEn <= '0'; -- save result
|
||||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||||
ocLoadInstr <= '0'; -- do not load instruction
|
ocLoadInstr <= '0'; -- do not load instruction
|
||||||
|
Loading…
Reference in New Issue
Block a user