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} );
|
||||
}
|
||||
}
|
||||
|
95
src/CPU.vhd
95
src/CPU.vhd
@ -63,18 +63,25 @@ architecture Behavioral of CPU is
|
||||
|
||||
component RegFile is
|
||||
Port(
|
||||
iClk : in std_logic;
|
||||
iReset : in std_logic;
|
||||
|
||||
idDataIn : in DATA;
|
||||
idCarryIn : in std_logic;
|
||||
idZeroIn : in std_logic;
|
||||
|
||||
icLoadEn : in std_logic;
|
||||
|
||||
odDataOut : out DATA;
|
||||
odCarryOut : out std_logic;
|
||||
odZeroOut : out std_logic
|
||||
iClk : 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;
|
||||
idCarryIn : in std_logic;
|
||||
idZeroIn : in std_logic;
|
||||
|
||||
icLoadEn : in std_logic;
|
||||
|
||||
odCarryOut : out std_logic;
|
||||
odZeroOut : out std_logic
|
||||
);
|
||||
end component;
|
||||
|
||||
@ -95,18 +102,21 @@ architecture Behavioral of CPU is
|
||||
|
||||
component FetchDecode is
|
||||
Port(
|
||||
iClk : in std_logic;
|
||||
iReset : in std_logic;
|
||||
|
||||
idData : in DATA;
|
||||
icAddrSel : in std_logic;
|
||||
icLoadInstr : in std_logic;
|
||||
icJump : in std_logic;
|
||||
icNextPC : in std_logic;
|
||||
|
||||
odAddress : out ADDRESS;
|
||||
odImmidiate : out DATA;
|
||||
ocOperation : out OPTYPE
|
||||
iClk : in std_logic;
|
||||
iReset : in std_logic;
|
||||
|
||||
idData : in DATA;
|
||||
icAddrSel : in std_logic;
|
||||
icLoadInstr : in std_logic;
|
||||
icJump : in std_logic;
|
||||
icNextPC : in std_logic;
|
||||
|
||||
odAddress : out ADDRESS;
|
||||
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
|
||||
);
|
||||
end component;
|
||||
|
||||
@ -125,7 +135,7 @@ architecture Behavioral of CPU is
|
||||
);
|
||||
end component;
|
||||
|
||||
signal scOpCode : optype;
|
||||
signal scOpCode : optype;
|
||||
signal sdCarryRF : std_logic;
|
||||
signal sdZeroRF : std_logic;
|
||||
signal scRnotWRam : std_logic;
|
||||
@ -135,13 +145,18 @@ architecture Behavioral of CPU is
|
||||
signal scNextPC : std_logic;
|
||||
signal scAddrSel : std_logic;
|
||||
signal scJump : std_logic;
|
||||
signal sdAkkuRes : DATA;
|
||||
signal sdCarryAkku : std_logic;
|
||||
signal sdAkkuRes : DATA;
|
||||
signal sdCarryAkku : std_logic;
|
||||
signal sdZeroAkku : std_logic;
|
||||
signal sdDataOut : DATA;
|
||||
signal sdDataIn : DATA;
|
||||
signal sdAddress : ADDRESS;
|
||||
signal sdImmidiate : DATA;
|
||||
signal sdDataOut : DATA;
|
||||
signal sdDataIn : DATA;
|
||||
signal sdAddress : ADDRESS;
|
||||
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
|
||||
|
||||
@ -163,21 +178,26 @@ begin
|
||||
RF: RegFile PORT MAP(
|
||||
iClk => iClk,
|
||||
iReset => iReset,
|
||||
|
||||
|
||||
icRegAsel => sdRegAsel,
|
||||
icRegBsel => sdRegBsel,
|
||||
icRegINsel => sdRegINsel,
|
||||
|
||||
idDataIn => sdAkkuRes,
|
||||
idCarryIn => sdCarryAkku,
|
||||
idZeroIn => sdZeroAkku,
|
||||
|
||||
icLoadEn => scLoadEn,
|
||||
|
||||
odDataOut => sdDataOut,
|
||||
odRegA => sdRegA,
|
||||
odRegB => sdRegB,
|
||||
odCarryOut => sdCarryRF,
|
||||
odZeroOut => sdZeroRF
|
||||
);
|
||||
|
||||
Calc : ALU Port MAP(
|
||||
idOperand1 => sdDataOut,
|
||||
idOperand2 => sdDataIn,
|
||||
idOperand1 => sdRegA,
|
||||
idOperand2 => sdRegB,
|
||||
idImmidiate => sdImmidiate,
|
||||
idCarryIn => sdCarryRF,
|
||||
|
||||
@ -200,6 +220,9 @@ begin
|
||||
|
||||
odAddress => sdAddress,
|
||||
odImmidiate => sdImmidiate,
|
||||
odRegAsel => sdRegAsel,
|
||||
odRegBsel => sdRegBsel,
|
||||
odRegINsel => sdRegINsel,
|
||||
ocOperation => scOpCode
|
||||
);
|
||||
|
||||
@ -212,7 +235,7 @@ begin
|
||||
icBusCtrlCPU => scRnotWRam,
|
||||
icRAMEnable => scEnableRAM,
|
||||
odDataOutCPU => sdDataIn,
|
||||
idDataInCPU => sdDataOut,
|
||||
idDataInCPU => sdRegA,
|
||||
idAddressCPU => sdAddress
|
||||
);
|
||||
|
||||
|
@ -46,7 +46,11 @@ entity FetchDecode is
|
||||
|
||||
odAddress : out ADDRESS;
|
||||
odImmidiate : out DATA;
|
||||
ocOperation : out OPTYPE
|
||||
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
|
||||
|
||||
);
|
||||
end FetchDecode;
|
||||
|
||||
@ -55,21 +59,32 @@ architecture Behavioral of FetchDecode is
|
||||
signal sdAdr, sdAdr_next : ADDRESS;
|
||||
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;
|
||||
|
||||
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
|
||||
-- defaults
|
||||
sdAdr_next <= sdAdr;
|
||||
sdPC_next <= sdPC;
|
||||
scOp_next <= scOp;
|
||||
sdImmidiate_next <= sdImmidate;
|
||||
|
||||
|
||||
sdRegAsel_next <= sdRegAsel;
|
||||
sdRegBsel_next <= sdRegBsel;
|
||||
sdRegINsel_next <= sdRegINsel;
|
||||
|
||||
--! ISA Definition
|
||||
if (icLoadInstr = '1') then
|
||||
sdAdr_next <= idData(15 downto 0);
|
||||
sdAdr_next <= "0000" & idData(11 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
|
||||
when "000000" => scOp_next <= shl;
|
||||
@ -111,13 +126,20 @@ begin
|
||||
sdPC <= (others => '0');
|
||||
sdAdr <= (others => '0');
|
||||
sdImmidate <= (others=>'0');
|
||||
sdRegAsel <= (others=>'0');
|
||||
sdRegBsel <= (others=>'0');
|
||||
sdRegINsel <= (others=>'0');
|
||||
|
||||
scOp <= hlt;
|
||||
|
||||
|
||||
elsif (rising_edge(iClk)) then
|
||||
sdPC <= sdPC_next;
|
||||
sdAdr <= sdAdr_next;
|
||||
scOp <= scOp_next;
|
||||
sdImmidate <= sdImmidiate_next;
|
||||
sdRegAsel <= sdRegAsel_next;
|
||||
sdRegBsel <= sdRegBsel_next;
|
||||
sdRegINsel <= sdRegINsel_next;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
@ -131,5 +153,11 @@ begin
|
||||
scOp_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;
|
||||
|
||||
|
@ -52,7 +52,7 @@ architecture Behavioral of MemInterface is
|
||||
begin
|
||||
|
||||
ocRnotW <= icBusCtrlCPU;
|
||||
odAddress <= idAddressCPU;
|
||||
odAddress <= idAddressCPU when icRAMEnable='1' else (others=>'0');
|
||||
ocEnable <= icRAMEnable;
|
||||
|
||||
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
|
||||
|
||||
constant Prog1 : MEMORY := ( --! 4k * 32bit of RAM
|
||||
0 => B"001111_000_000_000_0_0000000000000101", -- li 5
|
||||
1 => B"000010_000_000_000_0_0000000000100000", -- sto 32
|
||||
2 => B"111111_000_000_000_0_0000000000000000", -- hlt
|
||||
-- 0 => B"0011_000000001010", -- loa 10 (n)
|
||||
-- 1 => B"1100_000000001000", -- jpz 8
|
||||
-- 2 => B"0101_000000001100", -- sub <1>
|
||||
-- 3 => B"0010_000000001010", -- sto 10 (n)
|
||||
-- 4 => B"0011_000000001011", -- loa 11 (a)
|
||||
-- 5 => B"0100_000000001001", -- add <result>
|
||||
-- 6 => B"0010_000000001001", -- sto <result>
|
||||
-- 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
|
||||
1 => B"00111100001000000000000000000101", --lui $1, 5
|
||||
2 => B"00111100010000000000000000000110", --lui $2, 6
|
||||
3 => B"00111100011000000000000000000000", --lui $3, 0
|
||||
4 => B"00111100100000000000000000000001", --lui $4, 1
|
||||
5 => B"00010000101000000001000000000000", --add $5, $0, $2
|
||||
6 => B"00010000011000110000100000000000", --add $3, $3, $1
|
||||
7 => B"00010100101001010010000000000000", --sub $5, $5, $4
|
||||
8 => B"00110000000000000000000000001010", --jpz end
|
||||
9 => B"00111000000000000000000000000110", --jmp loop
|
||||
10 => B"11111100000000000000000000000000", --hlt
|
||||
|
||||
|
||||
|
||||
others => (others => '0')
|
||||
|
@ -22,49 +22,61 @@ use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
library work;
|
||||
use work.cpupkg.all;
|
||||
-- Uncomment the following library declaration if using
|
||||
-- arithmetic functions with Signed or Unsigned values
|
||||
--use IEEE.NUMERIC_STD.ALL;
|
||||
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
|
||||
Port(
|
||||
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;
|
||||
idCarryIn : in std_logic;
|
||||
idZeroIn : in std_logic;
|
||||
|
||||
icLoadEn : in std_logic;
|
||||
|
||||
odDataOut : out DATA;
|
||||
odCarryOut : out std_logic;
|
||||
odZeroOut : out std_logic
|
||||
);
|
||||
end RegFile;
|
||||
|
||||
architecture Behavioral of RegFile is
|
||||
|
||||
type registerFileType is array (0 to 31) of DATA;
|
||||
signal registerFile : registerFileType;
|
||||
|
||||
signal sdData : DATA;
|
||||
signal sdCarry : std_logic;
|
||||
signal sdZero : std_logic;
|
||||
begin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Execute Transition
|
||||
process(iClk, iReset)
|
||||
begin
|
||||
if (iReset = '1') then
|
||||
sdData <= (others => '0');
|
||||
for i in 31 downto 0 loop
|
||||
registerFile(i) <= (others=>'0');
|
||||
end loop;
|
||||
|
||||
sdCarry <= '0';
|
||||
sdZero <= '0';
|
||||
|
||||
elsif (rising_edge(iClk)) then
|
||||
if (icLoadEn = '1') then
|
||||
sdData <= idDataIn;
|
||||
registerFile(to_integer(unsigned(icRegINsel))) <= idDataIn;
|
||||
sdCarry <= idCarryIn;
|
||||
sdZero <= idZeroIn;
|
||||
|
||||
@ -73,9 +85,10 @@ begin
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
-- Output
|
||||
odDataOut <= sdData;
|
||||
|
||||
|
||||
odRegA <= registerFile(to_integer(unsigned(icRegAsel)));
|
||||
odRegB <= registerFile(to_integer(unsigned(icRegBsel)));
|
||||
odCarryOut <= sdCarry;
|
||||
odZeroOut <= sdZero;
|
||||
|
||||
|
@ -103,55 +103,55 @@ begin
|
||||
|
||||
when load =>
|
||||
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
|
||||
ocLoadInstr <= '0'; -- load instruction
|
||||
ocNextPC <= '0'; -- do not increment pc
|
||||
ocNextPC <= '0'; -- do not increment pc
|
||||
ocAddrSel <= '1'; -- pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when decode =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- do not save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocLoadEn <= '0'; -- do not save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '1'; -- load instruction
|
||||
ocNextPC <= '1'; -- do not increment pc
|
||||
ocNextPC <= '1'; -- do not increment pc
|
||||
ocAddrSel <= '0'; -- pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exshl =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exshr =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exsto =>
|
||||
ocRnotWRam <= '0'; -- write to RAM
|
||||
ocLoadEn <= '0'; -- do not save result
|
||||
ocLoadEn <= '0'; -- do not save result
|
||||
ocEnableRAM <= '1'; -- put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exloa =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
@ -165,118 +165,118 @@ begin
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exadd =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exsub =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exaddc =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exsubc =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exopor =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exopand =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exopxor =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exopnot =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '1'; -- do not put akku on databus
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '1'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when exjpz =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '1'; -- ocJump
|
||||
|
||||
when exjpc =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '1'; -- ocJump
|
||||
|
||||
when exjmp =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '1'; -- ocJump
|
||||
when exhlt =>
|
||||
ocRnotWRam <= '1'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocRnotWRam <= '0'; -- read from RAM
|
||||
ocLoadEn <= '0'; -- save result
|
||||
ocEnableRAM <= '0'; -- do not put akku on databus
|
||||
ocLoadInstr <= '0'; -- do not load instruction
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocNextPC <= '0'; -- increment pc
|
||||
ocAddrSel <= '0'; -- no pc on addressbus
|
||||
ocJump <= '0'; -- no ocJump
|
||||
|
||||
when others =>
|
||||
ocRnotWRam <= '-'; -- read from RAM
|
||||
ocLoadEn <= '-'; -- save result
|
||||
ocLoadEn <= '-'; -- save result
|
||||
ocEnableRAM <= '-'; -- do not put akku on databus
|
||||
ocLoadInstr <= '-'; -- do not load instruction
|
||||
ocNextPC <= '-'; -- increment pc
|
||||
ocNextPC <= '-'; -- increment pc
|
||||
ocAddrSel <= '-'; -- no pc on addressbus
|
||||
ocJump <= '-'; -- no ocJump
|
||||
end case;
|
||||
|
Loading…
Reference in New Issue
Block a user