Created
March 22, 2012 21:22
-
-
Save Feder1co5oave/2164665 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* DESCRIZIONE DEL PROCESSORE mE88 CON IMPLEMENTATO IL MECCANISMO DELLE | |
INTERRUZIONI E DELLA PROTEZIONE | |
Il processore parte in modo sistema. | |
Tramite l'istruzione STUM può passare definitivamente in modo utente. | |
In modo utente, l'esecuzione di un'istruzione INT o l'arrivo di un'interruzione. | |
hardware riportano il processore in modo sistema, mentre la terminazione | |
delle primitive o delle routine di risposta riporta il processore nel modo | |
*precedente*. | |
La protezione prevede la protezione dall'esecuzione di alcune istruzioni | |
privilegiate, la protezione dalla scrittura dei primi 256kb di memoria | |
principale e dall'utilizzo di due stack separate utente/sistema. | |
*/ | |
module Processore(...); | |
reg [15:0] PREV_SS, PREV_SP; | |
reg [5:0] FLAG; | |
function [7:0] first_fetch_state(f); | |
first_fetch_state = (f == 'B000) ? fetch_F0_0 : | |
(f == 'B001) ? fetch_F1_0 : | |
(f == 'B010) ? fetch_F2_0 : | |
(f == 'B011) ? fetch_F3_0 : | |
(f == 'B100) ? fetch_F4_0 : | |
(f == 'B101) ? fetch_F5_0 : | |
(f == 'B110) ? fetch_F6_0 : fetch_F7_0; | |
endfunction | |
/** | |
* Istruzioni protette: | |
* HLT F0 |00010101| | |
* IRET F0 |00010110| | |
* CLI F0 |00010111| | |
* STI F0 |00011000| | |
* LDPSR F0 |00011001| | |
* STUM F0 |00011010| | |
* IN F4 |10000110|_____offset_____| | |
* OUT F5 |10100001|_____offset_____| | |
*/ | |
function [1:0] valid_instruction(oc, us); | |
... | |
endfunction | |
always @(posedge p or negedge reset_) | |
if (reset_ == 0) begin | |
... | |
FLAG <= 0; // system mode | |
end else | |
casex (STAR) | |
... | |
fetch0: begin | |
IP <= IP + 1; MAR <= mml(CS, IP); DIR <= 0; MR_ <= 0; | |
STAR <= fetch1; end | |
fetch1: STAR <= fetch2; // wait | |
fetch2: begin | |
OPCODE <= data; MR_ <= 1; MJR <= first_fetch_state(data[7:5]); | |
STAR <= (valid_instruction(data, FLAG[5] /* U/S flag */) == | |
'B11) ? fetch3 : nvi0; end | |
fetch3: begin | |
MJR <= first_execution_state(OPCODE); STAR <= MJR; end | |
fetch_F0_0: STAR <= MJR; // |000XXXXX| | |
... | |
fetch_F3_0: begin // |011XXXXX|___src__| | |
IP <= IP + 1; MAR <= mml(CS, IP); MR_ <= 0; | |
STAR <= fetch_F3_1; end | |
fetch_F3_1: begin | |
SOURCE <= data; MR_ <= 1; STAR <= MJR; end | |
... | |
iret0: | |
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Feder1co 5oave | |
/* DESCRIZIONE DEL PROCESSORE mE88 CON IMPLEMENTATO IL MECCANISMO DELLE | |
INTERRUZIONI E DELLA PROTEZIONE | |
Il processore parte in modo sistema. (flag US = 0) | |
Tramite l'istruzione STUM può passare definitivamente in modo utente. (US = 1) | |
In modo utente, l'esecuzione di un'istruzione INT o l'arrivo di un'interruzione. | |
hardware riportano il processore in modo sistema, mentre la terminazione | |
delle primitive o delle routine di risposta riporta il processore nel modo | |
*precedente*. | |
La protezione prevede la protezione dall'esecuzione di alcune istruzioni | |
privilegiate, la protezione dalla scrittura dei primi 256kb di memoria | |
principale e l'utilizzo di due stack separate utente/sistema. | |
Per implementare la doppia stack vengono introdotti due registri fotocopia di SS | |
e SP, con i quali vengono scambiati al passaggio da una pila all'altra. | |
L'istruzione LDPSR serve appositamente a inizializzare i registri PREV_S* | |
per il primo utilizzo. Dovrebbe essere utilizzata dal software di sistema | |
all'accensione per settare l'indirizzo di partenza della pila di sistema. | |
Si ricorda che, quindi, all'esecuzione di un'istruzione INT o all'arrivo di | |
un'interrupt hardware, deve succedere questo: | |
- recupero del tipo dell'interrupt, se è hardware | |
- uso della pila di sistema (scambio dei registri SS e SP con le loro copie, se | |
necessario) | |
- push flag | |
- push ip | |
- push cs | |
- cli (reset completo del registro dei flag) | |
- caricamento dell'indirizzo della routine (dal vettore delle routine a CS e IP) | |
- chiamata della routine | |
L'istruzione IRET si comporta di conseguenza e in modo speculare. | |
*/ | |
module Processore(...); | |
reg [15:0] PREV_SS, PREV_SP; | |
reg [5:0] FLAG; | |
wire f_intr; | |
assign f_intr = (intr & FLAG[5]); | |
function [7:0] first_fetch_state(f); | |
first_fetch_state = (f == 'B000) ? fetch_F0_0 : | |
(f == 'B001) ? fetch_F1_0 : | |
(f == 'B010) ? fetch_F2_0 : | |
(f == 'B011) ? fetch_F3_0 : | |
(f == 'B100) ? fetch_F4_0 : | |
(f == 'B101) ? fetch_F5_0 : | |
(f == 'B110) ? fetch_F6_0 : fetch_F7_0; | |
endfunction | |
/** | |
* Istruzioni protette: | |
* MnemonicoFormatoCodiceoperativo | |
* HLT F0 |00010101| | |
* IRET F0 |00010110| | |
* CLI F0 |00010111| | |
* STI F0 |00011000| | |
* LDPSR F0 |00011001| | |
* STUM F0 |00011010| | |
* IN F4 |10000110|_____offset_____| | |
* OUT F5 |10100001|_____offset_____| | |
*/ | |
function [1:0] valid_instruction(oc, us); | |
... | |
endfunction | |
always @(posedge p or negedge reset_) | |
if (reset_ == 0) begin | |
... | |
FLAG <= 0; // system mode, interruzioni mascherate | |
INTA <= 0; end | |
else casex (STAR) | |
... | |
fetch0: begin | |
IP <= IP + 1; MAR <= mml(CS, IP); DIR <= 0; MR_ <= 0; | |
STAR <= fetch1; end | |
fetch1: STAR <= fetch2; // wait | |
fetch2: begin | |
OPCODE <= data; MR_ <= 1; MJR <= first_fetch_state(data[7:5]); | |
STAR <= (valid_instruction(data, FLAG[5] /* U/S flag */) == | |
'B11) ? fetch3 : nvi0; end | |
fetch3: begin | |
MJR <= first_execution_state(OPCODE); STAR <= MJR; end | |
fetch_F0_0: STAR <= MJR; // |000XXXXX| | |
... | |
fetch_F3_0: begin // |011XXXXX|___src__| | |
IP <= IP + 1; MAR <= mml(CS, IP); MR_ <= 0; | |
STAR <= fetch_F3_1; end | |
fetch_F3_1: begin | |
SOURCE <= data; MR_ <= 1; STAR <= MJR; end | |
... | |
int0: begin | |
SS <= (FLAG[5] == 1) ? PREV_SS : SS; | |
PREV_SS <= (FLAG[5] == 1) ? SS : PREV_SS; | |
SP <= (FLAG[5] == 1) ? PREV_SP : SP; | |
PREV_SP <= (FLAG[5] == 1) ? SP : PREV_SP; STAR <= int1; end | |
int1: begin | |
SP <= SP - 1; MAR <= mml(SS, SP - 1); MBR <= {'B00, FLAG}; | |
FLAG <= 0; DIR <= 1; STAR <= int2; end | |
int2: begin | |
MW_ <= 0; STAR <= int3; end | |
int3: begin | |
MW_ <= 1; STAR <= int4; end | |
int4: begin | |
SP <= SP - 1; MAR <= mml(SS, SP - 1); MBR <= IP[15:8]; | |
STAR <= int5; end | |
int5: begin | |
MW_ <= 0; STAR <= int6; end | |
int6: begin | |
MW_ <= 1; STAR <= int7; end | |
int7: begin | |
SP <= SP - 1; MAR <= mml(SS, SP - 1); MBR <= IP[7:0]; | |
STAR <= int8; end | |
int8: begin | |
MW_ <= 0; STAR <= int9; end | |
int9: begin | |
MW_ <= 1; STAR <= int10; end | |
int10: begin | |
SP <= SP - 1; MAR <= mml(SS, SP - 1); MBR <= CS[15:8]; | |
STAR <= int11; end | |
int11: begin | |
MW_ <= 0; STAR <= int12; end | |
int12: begin | |
MW_ <= 1; STAR <= int13; end | |
int13: begin | |
SP <= SP - 1; MAR <= mml(SS, SP - 1); MBR <= CS[7:0]; | |
STAR <= int14; end | |
int14: begin | |
MW_ <= 0; STAR <= int15; end | |
int15: begin | |
MW_ <= 1; STAR <= int16; end | |
int16: begin | |
MAR <= mml(0, {6'B000000, SOURCE, 2'B00}); DIR <= 0; MR_ <= 0; | |
// MAR <= {10'B0000000000, SOURCE, 2'B00}; | |
STAR <= int17; | |
int17; STAR <= int18; // wait | |
int18: begin | |
MBR <= data; MAR <= MAR + 1; STAR <= int19; end | |
int19: STAR <= int20; // wait | |
int20: begin | |
IP <= {data, MBR}; MAR <= MAR + 1; STAR <= int21; end | |
int21: STAR <= int22; // wait | |
int22: begin | |
MBR <= data; MAR <= MAR + 1; STAR <= int23; end | |
int23: STAR <= int24; // wait | |
int24: begin | |
CS <= {data, MBR}; MR_ <= 1; STAR <= fetch0; end | |
iret0: begin | |
MAR <= mml(SS, SP); MR_ <= 0; DIR <= 0; SP <= SP + 1; | |
STAR <= iret1; end | |
iret1: STAR <= iret2; // wait | |
iret2: begin | |
MBR <= data; MAR <= mml(SS, SP); SP <= SP + 1; | |
STAR <= iret3; end | |
iret3: STAR <= iret4; // wait | |
iret4: begin | |
CS <= {data, MBR}; MAR <= mml(SS, SP); SP <= SP + 1; | |
STAR <= iret5; end | |
iret5: STAR <= iret6; // wait | |
iret6: begin | |
MBR <= data; MAR <= mml(SS, SP); SP <= SP + 1; | |
STAR <= iret7; end | |
iret7: STAR <= iret8; // wait | |
iret8: begin | |
IP <= {data, MBR}; MAR <= mml(SS, SP); SP <= SP + 1; | |
STAR <= iret9; end | |
iret9: STAR <= iret10; // wait | |
iret10: begin | |
FLAG <= data; STAR <= (f_intr == 1) ? pre_tipo0 : fetch0; | |
SS <= (data[5] == 1) ? PREV_SS : SS; | |
PREV_SS <= (data[5] == 1) ? SS : PREV_SS; | |
SP <= (data[5] == 1) ? PREV_SP : SP; | |
PREV_SP <= (data[5] == 1) ? SP : PREV_SP; MR_ <= 1; end | |
cli0: | |
FLAG <= {FLAG[5], 0, FLAG[3:0]}; | |
STAR <= (f_intr == 1) ? pre_tipo0 : fetch0; end | |
sti0: begin | |
FLAG <= {FLAG[5], 1, FLAG[3:0]}; | |
STAR <= (f_intr == 1) ? pre_tipo0 : fetch0; end | |
ldpsr0: begin | |
PREV_SS <= SS; PREV_SP <= SP; | |
STAR <= (f_intr == 1) ? pre_tipo0 : fetch0; end | |
stum0: begin | |
FLAG <= {1, FLAG[4:0]}; | |
STAR <= (f_intr == 1) ? pre_tipo0 : fetch0; end | |
pre_tipo0: begin | |
DIR <= 0; INTA <= 1; | |
STAR <= (intr == 0) ? pre_tipo1 : pre_tipo0; end | |
pre_tipo1: begin | |
SOURCE <= data; INTA <= 0; STAR <= int0; end | |
endcase | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment