Skip to content

Instantly share code, notes, and snippets.

@Feder1co5oave
Created March 22, 2012 21:22
Show Gist options
  • Save Feder1co5oave/2164665 to your computer and use it in GitHub Desktop.
Save Feder1co5oave/2164665 to your computer and use it in GitHub Desktop.
/* 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
// 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