OpenCores
URL https://opencores.org/ocsvn/thor/thor/trunk

Subversion Repositories thor

[/] [thor/] [trunk/] [FT64v7/] [rtl/] [common/] [FT64_ipt.v] - Diff between revs 61 and 66

Only display areas with differences | Details | Blame | View Log

Rev 61 Rev 66
// ============================================================================
// ============================================================================
//        __
//        __
//   \\__/ o\    (C) 2018-2019  Robert Finch, Waterloo
//   \\__/ o\    (C) 2018-2019  Robert Finch, Waterloo
//    \  __ /    All rights reserved.
//    \  __ /    All rights reserved.
//     \/_//     robfinch<remove>@finitron.ca
//     \/_//     robfinch<remove>@finitron.ca
//       ||
//       ||
//
//
//      FT64_ipt.v
//      FT64_ipt.v
//  - 64 bit CPU inverted page table memory management unit
//  - 64 bit CPU inverted page table memory management unit
//
//
// This source file is free software: you can redistribute it and/or modify 
// This source file is free software: you can redistribute it and/or modify 
// it under the terms of the GNU Lesser General Public License as published 
// it under the terms of the GNU Lesser General Public License as published 
// by the Free Software Foundation, either version 3 of the License, or     
// by the Free Software Foundation, either version 3 of the License, or     
// (at your option) any later version.                                      
// (at your option) any later version.                                      
//                                                                          
//                                                                          
// This source file is distributed in the hope that it will be useful,      
// This source file is distributed in the hope that it will be useful,      
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// but WITHOUT ANY WARRANTY; without even the implied warranty of           
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            
// GNU General Public License for more details.                             
// GNU General Public License for more details.                             
//                                                                          
//                                                                          
// You should have received a copy of the GNU General Public License        
// You should have received a copy of the GNU General Public License        
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
// along with this program.  If not, see <http://www.gnu.org/licenses/>.    
//
//
// ============================================================================
// ============================================================================
//
//
`ifndef TRUE
`ifndef TRUE
`define TRUE    1'b1
`define TRUE    1'b1
`define FALSE   1'b0
`define FALSE   1'b0
`endif
`endif
//`define BYPASS        1'b1
`define BYPASS  1'b1
 
 
module FT64_ipt(rst, clk, pkeys_i, ol_i, bte_i, cti_i, cs_i, icl_i, cyc_i, stb_i, ack_o, we_i, sel_i, vadr_i, dat_i, dat_o,
module FT64_ipt(rst, clk, pkeys_i, ol_i, bte_i, cti_i, cs_i, icl_i, cyc_i, stb_i, ack_o, we_i, sel_i, vadr_i, dat_i, dat_o,
        bte_o, cti_o, cyc_o, ack_i, we_o, sel_o, padr_o, exv_o, rdv_o, wrv_o, prv_o, page_fault);
        bte_o, cti_o, cyc_o, ack_i, we_o, sel_o, padr_o, exv_o, rdv_o, wrv_o, prv_o, page_fault);
input rst;
input rst;
input clk;
input clk;
input [63:0] pkeys_i;
input [63:0] pkeys_i;
input [1:0] ol_i;
input [1:0] ol_i;
input [1:0] bte_i;
input [1:0] bte_i;
input [2:0] cti_i;
input [2:0] cti_i;
input cs_i;
input cs_i;
input icl_i;
input icl_i;
input cyc_i;
input cyc_i;
input stb_i;
input stb_i;
output reg ack_o;
output reg ack_o;
input we_i;
input we_i;
input [7:0] sel_i;
input [7:0] sel_i;
input [63:0] vadr_i;
input [63:0] vadr_i;
input [63:0] dat_i;
input [63:0] dat_i;
output reg [63:0] dat_o;
output reg [63:0] dat_o;
output reg [1:0] bte_o;
output reg [1:0] bte_o;
output reg [2:0] cti_o;
output reg [2:0] cti_o;
output reg cyc_o;
output reg cyc_o;
input ack_i;
input ack_i;
output reg we_o;
output reg we_o;
output reg [7:0] sel_o;
output reg [7:0] sel_o;
output reg [31:0] padr_o;
output reg [31:0] padr_o;
output reg exv_o;
output reg exv_o;
output reg rdv_o;
output reg rdv_o;
output reg wrv_o;
output reg wrv_o;
output reg prv_o;
output reg prv_o;
output reg page_fault;
output reg page_fault;
 
 
parameter S_IDLE = 4'd0;
parameter S_IDLE = 4'd0;
parameter S_CMP1 = 4'd1;
parameter S_CMP1 = 4'd1;
parameter S_CMP2 = 4'd2;
parameter S_CMP2 = 4'd2;
parameter S_CMP3 = 4'd3;
parameter S_CMP3 = 4'd3;
parameter S_CMP4 = 4'd4;
parameter S_CMP4 = 4'd4;
parameter S_CMP5 = 4'd5;
parameter S_CMP5 = 4'd5;
parameter S_CMP6 = 4'd6;
parameter S_CMP6 = 4'd6;
parameter S_WAIT1 = 4'd7;
parameter S_WAIT1 = 4'd7;
parameter S_ACK = 4'd8;
parameter S_ACK = 4'd8;
parameter S_RESET = 4'd9;
parameter S_RESET = 4'd9;
 
 
integer n;
integer n;
wire [9:0] pkey [0:5];
wire [9:0] pkey [0:5];
assign pkey[0] = pkeys_i[9:0];
assign pkey[0] = pkeys_i[9:0];
assign pkey[1] = pkeys_i[19:10];
assign pkey[1] = pkeys_i[19:10];
assign pkey[2] = pkeys_i[29:20];
assign pkey[2] = pkeys_i[29:20];
assign pkey[3] = pkeys_i[39:30];
assign pkey[3] = pkeys_i[39:30];
assign pkey[4] = pkeys_i[49:40];
assign pkey[4] = pkeys_i[49:40];
assign pkey[5] = pkeys_i[59:50];
assign pkey[5] = pkeys_i[59:50];
reg [3:0] state;
reg [3:0] state;
reg [15:0] pt_ad;
reg [15:0] pt_ad;
reg upd;
reg upd;
reg upd_done;
reg upd_done;
reg probe, probe_done;
reg probe, probe_done;
reg pte_last;
reg pte_last;
reg [7:0] pte_asid;
reg [7:0] pte_asid;
reg [3:0] pte_drwx;
reg [3:0] pte_drwx;
reg [18:0] pte_vadr;
reg [18:0] pte_vadr;
reg [9:0] pte_key;
reg [9:0] pte_key;
reg pt_wr;
reg pt_wr;
reg [41:0] pt_dati;
reg [41:0] pt_dati;
wire [41:0] pt_dat;
wire [41:0] pt_dat;
 
 
FT64_iptram uram1 (
FT64_iptram uram1 (
  .clka(clk),
  .clka(clk),
  .ena(1'b1),
  .ena(1'b1),
  .wea(pt_wr),
  .wea(pt_wr),
  .addra(pt_ad),
  .addra(pt_ad),
  .dina(pt_dati),
  .dina(pt_dati),
  .douta(pt_dat)
  .douta(pt_dat)
);
);
 
 
wire pt_last = pt_dat[23];
wire pt_last = pt_dat[23];
wire [18:0] pt_vadr = pt_dat[22:4];
wire [18:0] pt_vadr = pt_dat[22:4];
wire [7:0] pt_asid = pt_dat[31:24];
wire [7:0] pt_asid = pt_dat[31:24];
wire [3:0] pt_drwx = pt_dat[3:0];
wire [3:0] pt_drwx = pt_dat[3:0];
wire [9:0] pt_key = pt_dat[41:32];
wire [9:0] pt_key = pt_dat[41:32];
 
 
reg keymatch;
reg keymatch;
always @*
always @*
begin
begin
keymatch = ol_i==2'b00;
keymatch = ol_i==2'b00;
for (n = 0; n < 6; n = n + 1)
for (n = 0; n < 6; n = n + 1)
        if (pt_key==pkey[n] || pt_key==10'h0)
        if (pt_key==pkey[n] || pt_key==10'h0)
                keymatch = 1'b1;
                keymatch = 1'b1;
end
end
 
 
function [15:0] Hash1;
function [15:0] Hash1;
input [39:0] vadr;
input [39:0] vadr;
begin
begin
        Hash1 = {1'b0,vadr[37:32],vadr[21:13]};
        Hash1 = {1'b0,vadr[37:32],vadr[21:13]};
end
end
endfunction
endfunction
 
 
function [15:0] Hash2;
function [15:0] Hash2;
input [39:0] vadr;
input [39:0] vadr;
begin
begin
        Hash2 = {1'b1,vadr[37:32],vadr[21:13]};
        Hash2 = {1'b1,vadr[37:32],vadr[21:13]};
end
end
endfunction
endfunction
 
 
always @(posedge clk)
always @(posedge clk)
        case(vadr_i[5:3])
        case(vadr_i[5:3])
        3'd1:
        3'd1:
                dat_o <= pt_ad;
                dat_o <= pt_ad;
        3'd2:
        3'd2:
                begin
                begin
                        dat_o[41:32] <= pte_key;
                        dat_o[41:32] <= pte_key;
                        dat_o[31:24] <= pte_asid;
                        dat_o[31:24] <= pte_asid;
                        dat_o[23] <= pte_last;
                        dat_o[23] <= pte_last;
                        dat_o[2:0] <= pte_drwx[2:0];
                        dat_o[2:0] <= pte_drwx[2:0];
                        dat_o[7] <= pte_drwx[3];
                        dat_o[7] <= pte_drwx[3];
                end
                end
        3'd3:
        3'd3:
                dat_o <= pte_vadr;
                dat_o <= pte_vadr;
        default:        dat_o <= 1'b0;
        default:        dat_o <= 1'b0;
        endcase
        endcase
 
 
always @(posedge clk)
always @(posedge clk)
        bte_o <= bte_i;
        bte_o <= bte_i;
always @(posedge clk)
always @(posedge clk)
        cti_o <= cti_i;
        cti_o <= cti_i;
always @(posedge clk)
always @(posedge clk)
        sel_o <= sel_i;
        sel_o <= sel_i;
`ifdef BYPASS
`ifdef BYPASS
always @(posedge clk)
always @(posedge clk)
 
        pt_wr <= 1'b0;
 
always @(posedge clk)
 
        pt_ad <= 16'h0;
 
always @(posedge clk)
 
        pt_dati <= 42'h0;
 
always @(posedge clk)
        cyc_o <= cyc_i;
        cyc_o <= cyc_i;
always @(posedge clk)
always @(posedge clk)
        we_o <= we_i;
        we_o <= we_i;
always @(posedge clk)
always @(posedge clk)
        padr_o <= vadr_i[31:0];
        padr_o <= vadr_i[31:0];
always @(posedge clk)
always @(posedge clk)
        exv_o <= 1'b0;
        exv_o <= 1'b0;
always @(posedge clk)
always @(posedge clk)
        rdv_o <= 1'b0;
        rdv_o <= 1'b0;
always @(posedge clk)
always @(posedge clk)
        wrv_o <= 1'b0;
        wrv_o <= 1'b0;
always @(posedge clk)
always @(posedge clk)
        prv_o <= 1'b0;
        prv_o <= 1'b0;
always @(posedge clk)
always @(posedge clk)
        page_fault <= 1'b0;
        page_fault <= 1'b0;
 
always @(posedge clk)
 
        ack_o <= 1'b0;
`else
`else
always @(posedge clk)
always @(posedge clk)
if (rst) begin
if (rst) begin
        cyc_o <= 1'b0;
        cyc_o <= 1'b0;
        padr_o <= 32'hFFFC0100;
        padr_o <= 32'hFFFC0100;
        ack_o <= 1'b0;
        ack_o <= 1'b0;
        exv_o <= 1'b0;
        exv_o <= 1'b0;
        rdv_o <= 1'b0;
        rdv_o <= 1'b0;
        wrv_o <= 1'b0;
        wrv_o <= 1'b0;
        prv_o <= 1'b0;
        prv_o <= 1'b0;
        pt_wr <= 1'b1;
        pt_wr <= 1'b1;
        pt_ad <= 1'b0;
        pt_ad <= 1'b0;
        pt_dati <= 1'b0;
        pt_dati <= 1'b0;
        upd <= 1'b0;
        upd <= 1'b0;
        probe <= 1'b0;
        probe <= 1'b0;
        upd_done <= 1'b0;
        upd_done <= 1'b0;
        probe_done <= 1'b0;
        probe_done <= 1'b0;
        goto(S_IDLE);
        goto(S_IDLE);
end
end
else begin
else begin
        pt_wr <= 1'b0;
        pt_wr <= 1'b0;
        page_fault <= 1'b0;
        page_fault <= 1'b0;
        ack_o <= 1'b0;
        ack_o <= 1'b0;
case(state)
case(state)
// Clear page table ram on reset.
// Clear page table ram on reset.
S_RESET:
S_RESET:
        begin
        begin
                pt_ad <= pt_ad + 2'd1;
                pt_ad <= pt_ad + 2'd1;
                if (&pt_ad) begin
                if (&pt_ad) begin
                        pt_wr <= 1'b0;
                        pt_wr <= 1'b0;
                        state <= S_IDLE;
                        state <= S_IDLE;
                end
                end
        end
        end
S_IDLE:
S_IDLE:
        if (cyc_i) begin
        if (cyc_i) begin
                if (cs_i & stb_i) begin
                if (cs_i & stb_i) begin
                        ack_o <= 1'b1;
                        ack_o <= 1'b1;
                        case(vadr_i[5:3])
                        case(vadr_i[5:3])
                        3'd0:
                        3'd0:
                                begin
                                begin
                                        if (dat_i[0] & !upd_done) begin
                                        if (dat_i[0] & !upd_done) begin
                                                pt_ad <= Hash1({pte_asid,pte_vadr});
                                                pt_ad <= Hash1({pte_asid,pte_vadr});
                                                upd <= 1'b1;
                                                upd <= 1'b1;
                                                goto(S_CMP1);
                                                goto(S_CMP1);
                                        end
                                        end
                                        else if (dat_i[1] & !probe_done) begin
                                        else if (dat_i[1] & !probe_done) begin
                                                pt_ad <= Hash1({pte_asid,pte_vadr});
                                                pt_ad <= Hash1({pte_asid,pte_vadr});
                                                probe <= 1'b1;
                                                probe <= 1'b1;
                                                goto(S_CMP1);
                                                goto(S_CMP1);
                                        end
                                        end
                                end
                                end
                        3'd2:
                        3'd2:
                                begin
                                begin
                                        pte_key  <= dat_i[41:32];
                                        pte_key  <= dat_i[41:32];
                                        pte_asid <= dat_i[31:24];
                                        pte_asid <= dat_i[31:24];
                                        pte_last <= dat_i[22];
                                        pte_last <= dat_i[22];
                                        pte_drwx <= {dat_i[7],dat_i[2:0]};
                                        pte_drwx <= {dat_i[7],dat_i[2:0]};
                                end
                                end
                        3'd3:
                        3'd3:
                                begin
                                begin
                                        pte_vadr <= dat_i[18:0];
                                        pte_vadr <= dat_i[18:0];
                                end
                                end
                        endcase
                        endcase
                end
                end
                else begin
                else begin
                        upd_done <= 1'b0;
                        upd_done <= 1'b0;
                        probe_done <= 1'b0;
                        probe_done <= 1'b0;
                        upd <= 1'b0;
                        upd <= 1'b0;
                        probe <= 1'b0;
                        probe <= 1'b0;
                        if (ol_i==2'b0) begin
                        if (ol_i==2'b0) begin
                                cyc_o <= 1'b1;
                                cyc_o <= 1'b1;
                                we_o <= we_i;
                                we_o <= we_i;
                                padr_o <= vadr_i[31:0];
                                padr_o <= vadr_i[31:0];
                                goto(S_ACK);
                                goto(S_ACK);
                        end
                        end
                        else begin
                        else begin
                                // Video frame buffer ($00xxxxxx) and ROM / IO ($FFxxxxxx) regions are
                                // Video frame buffer ($00xxxxxx) and ROM / IO ($FFxxxxxx) regions are
                                // not mapped.
                                // not mapped.
                                if (vadr_i[31:24]==8'hFF || vadr_i[31:24]==8'h00) begin
                                if (vadr_i[31:24]==8'hFF || vadr_i[31:24]==8'h00) begin
                                        cyc_o <= 1'b1;
                                        cyc_o <= 1'b1;
                                        we_o <= we_i;
                                        we_o <= we_i;
                                        padr_o <= vadr_i[31:0];
                                        padr_o <= vadr_i[31:0];
                                        goto(S_ACK);
                                        goto(S_ACK);
                                end
                                end
                                else begin
                                else begin
                                        pt_ad <= Hash1({vadr_i[63:56],vadr_i});
                                        pt_ad <= Hash1({vadr_i[63:56],vadr_i});
                                        goto(S_CMP1);
                                        goto(S_CMP1);
                                end
                                end
                        end
                        end
                end
                end
        end
        end
        else begin
        else begin
                exv_o <= 1'b0;
                exv_o <= 1'b0;
                rdv_o <= 1'b0;
                rdv_o <= 1'b0;
                wrv_o <= 1'b0;
                wrv_o <= 1'b0;
                prv_o <= 1'b0;
                prv_o <= 1'b0;
        end
        end
 
 
S_CMP1:
S_CMP1:
        goto(S_CMP2);
        goto(S_CMP2);
S_CMP2:
S_CMP2:
        goto(S_CMP3);
        goto(S_CMP3);
S_CMP3:
S_CMP3:
        if (pt_drwx[2:0]==3'b0) begin
        if (pt_drwx[2:0]==3'b0) begin
                if (upd) begin
                if (upd) begin
                        pte_key  <= 10'h0;
                        pte_key  <= 10'h0;
                        pte_last <= 1'b0;
                        pte_last <= 1'b0;
                        pte_drwx <= 4'd0;
                        pte_drwx <= 4'd0;
                        pt_wr <= 1'b1;
                        pt_wr <= 1'b1;
                        pt_dati <= {pte_key,pte_asid,pte_last,pte_vadr[18:0],pte_drwx};
                        pt_dati <= {pte_key,pte_asid,pte_last,pte_vadr[18:0],pte_drwx};
                        upd_done <= 1'b1;
                        upd_done <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else if (probe) begin
                else if (probe) begin
                        pte_drwx <= 3'b0;
                        pte_drwx <= 3'b0;
                        pte_vadr <= 19'b0;
                        pte_vadr <= 19'b0;
                        pte_asid <= 8'b0;
                        pte_asid <= 8'b0;
                        pte_last <= 1'b0;
                        pte_last <= 1'b0;
                        pte_key  <= 10'h0;
                        pte_key  <= 10'h0;
                        probe_done <= 1'b1;
                        probe_done <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else begin
                else begin
                        page_fault <= 1'b1;
                        page_fault <= 1'b1;
                        goto(S_WAIT1);
                        goto(S_WAIT1);
                end
                end
        end
        end
        else if (pt_asid==vadr_i[63:56] && pt_vadr==vadr_i[31:13]) begin
        else if (pt_asid==vadr_i[63:56] && pt_vadr==vadr_i[31:13]) begin
                if (upd) begin
                if (upd) begin
                        if (keymatch) begin
                        if (keymatch) begin
                                pte_key  <= pt_key;
                                pte_key  <= pt_key;
                                pte_last <= pt_last;
                                pte_last <= pt_last;
                                pte_drwx <= pt_drwx;
                                pte_drwx <= pt_drwx;
                                pt_wr <= 1'b1;
                                pt_wr <= 1'b1;
                                pt_dati <= {pte_key,pt_dat[31:4],pte_drwx};
                                pt_dati <= {pte_key,pt_dat[31:4],pte_drwx};
                        end
                        end
                        else
                        else
                                prv_o <= 1'b1;
                                prv_o <= 1'b1;
                        upd_done <= 1'b1;
                        upd_done <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else if (probe) begin
                else if (probe) begin
                        if (keymatch) begin
                        if (keymatch) begin
                                pte_key  <= pt_key;
                                pte_key  <= pt_key;
                                pte_last <= pt_last;
                                pte_last <= pt_last;
                                pte_drwx <= pt_drwx;
                                pte_drwx <= pt_drwx;
                        end
                        end
                        else
                        else
                                prv_o <= 1'b1;
                                prv_o <= 1'b1;
                        probe_done <= 1'b1;
                        probe_done <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else if (~ack_i) begin
                else if (~ack_i) begin
                        if (keymatch) begin
                        if (keymatch) begin
                                cyc_o <= 1'b1;
                                cyc_o <= 1'b1;
                                we_o <= we_i & pt_drwx[1];
                                we_o <= we_i & pt_drwx[1];
                                if (!pt_drwx[1] & we_i) wrv_o <= 1'b1;
                                if (!pt_drwx[1] & we_i) wrv_o <= 1'b1;
                                if (!pt_drwx[2] & ~we_i) rdv_o <= 1'b1;
                                if (!pt_drwx[2] & ~we_i) rdv_o <= 1'b1;
                                if (!pt_drwx[0] & icl_i) exv_o <= 1'b1;
                                if (!pt_drwx[0] & icl_i) exv_o <= 1'b1;
                                padr_o <= {pt_ad,vadr_i[12:0]};
                                padr_o <= {pt_ad,vadr_i[12:0]};
                        end
                        end
                        else begin
                        else begin
                                cyc_o <= 1'b1;
                                cyc_o <= 1'b1;
                                we_o <= 1'b0;
                                we_o <= 1'b0;
                                padr_o <= 32'hFFFFFFF8;
                                padr_o <= 32'hFFFFFFF8;
                                prv_o <= 1'b1;
                                prv_o <= 1'b1;
                        end
                        end
                        goto(S_ACK);
                        goto(S_ACK);
                end
                end
        end
        end
        else begin
        else begin
                if (upd|probe)
                if (upd|probe)
                        pt_ad <= Hash2({pte_asid,pte_vadr});
                        pt_ad <= Hash2({pte_asid,pte_vadr});
                else
                else
                        pt_ad <= Hash2({vadr_i[63:56],vadr_i});
                        pt_ad <= Hash2({vadr_i[63:56],vadr_i});
                goto(S_CMP4);
                goto(S_CMP4);
        end
        end
 
 
S_CMP4:
S_CMP4:
        goto(S_CMP5);
        goto(S_CMP5);
S_CMP5:
S_CMP5:
        goto(S_CMP6);
        goto(S_CMP6);
S_CMP6:
S_CMP6:
        if (pt_drwx[2:0]==3'b0) begin
        if (pt_drwx[2:0]==3'b0) begin
                if (upd) begin
                if (upd) begin
                        pte_key  <= 10'h0;
                        pte_key  <= 10'h0;
                        pte_last <= 1'b0;
                        pte_last <= 1'b0;
                        pte_drwx <= 4'd0;
                        pte_drwx <= 4'd0;
                        pt_wr <= 1'b1;
                        pt_wr <= 1'b1;
                        pt_dati <= {pte_key,pte_asid,pte_last,pte_vadr[18:0],pte_drwx};
                        pt_dati <= {pte_key,pte_asid,pte_last,pte_vadr[18:0],pte_drwx};
                        upd_done <= 1'b1;
                        upd_done <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else if (probe) begin
                else if (probe) begin
                        pte_key  <= 10'h0;
                        pte_key  <= 10'h0;
                        pte_drwx <= 43'b0;
                        pte_drwx <= 43'b0;
                        pte_vadr <= 19'b0;
                        pte_vadr <= 19'b0;
                        pte_asid <= 8'b0;
                        pte_asid <= 8'b0;
                        pte_last <= 1'b0;
                        pte_last <= 1'b0;
                        probe_done <= 1'b1;
                        probe_done <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else begin
                else begin
                        page_fault <= 1'b1;
                        page_fault <= 1'b1;
                        goto(S_WAIT1);
                        goto(S_WAIT1);
                end
                end
        end
        end
        else if (pt_asid==vadr_i[63:56] && pt_vadr==vadr_i[31:13]) begin
        else if (pt_asid==vadr_i[63:56] && pt_vadr==vadr_i[31:13]) begin
                if (upd) begin
                if (upd) begin
                        if (keymatch) begin
                        if (keymatch) begin
                                pte_key  <= pt_key;
                                pte_key  <= pt_key;
                                pte_last <= pt_last;
                                pte_last <= pt_last;
                                pte_drwx <= pt_drwx;
                                pte_drwx <= pt_drwx;
                                pt_wr <= 1'b1;
                                pt_wr <= 1'b1;
                                pt_dati <= {pte_key,pt_dat[31:4],pte_drwx};
                                pt_dati <= {pte_key,pt_dat[31:4],pte_drwx};
                        end
                        end
                        else
                        else
                                prv_o <= 1'b1;
                                prv_o <= 1'b1;
                        upd_done <= 1'b1;
                        upd_done <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else if (probe) begin
                else if (probe) begin
                        if (keymatch) begin
                        if (keymatch) begin
                                pte_key  <= pt_key;
                                pte_key  <= pt_key;
                                pte_last <= pt_last;
                                pte_last <= pt_last;
                                pte_drwx <= pt_drwx;
                                pte_drwx <= pt_drwx;
                                probe_done <= 1'b1;
                                probe_done <= 1'b1;
                        end
                        end
                        else
                        else
                                prv_o <= 1'b1;
                                prv_o <= 1'b1;
                        goto(S_IDLE);
                        goto(S_IDLE);
                end
                end
                else if (~ack_i) begin
                else if (~ack_i) begin
                        if (keymatch) begin
                        if (keymatch) begin
                                cyc_o <= 1'b1;
                                cyc_o <= 1'b1;
                                we_o <= we_i & pt_drwx[1];
                                we_o <= we_i & pt_drwx[1];
                                if (!pt_drwx[1] & we_i) wrv_o <= 1'b1;
                                if (!pt_drwx[1] & we_i) wrv_o <= 1'b1;
                                if (!pt_drwx[2] & ~we_i) rdv_o <= 1'b1;
                                if (!pt_drwx[2] & ~we_i) rdv_o <= 1'b1;
                                if (!pt_drwx[0] & icl_i) exv_o <= 1'b1;
                                if (!pt_drwx[0] & icl_i) exv_o <= 1'b1;
                                padr_o <= {pt_ad,vadr_i[12:0]};
                                padr_o <= {pt_ad,vadr_i[12:0]};
                        end
                        end
                        else begin
                        else begin
                                cyc_o <= 1'b1;
                                cyc_o <= 1'b1;
                                we_o <= 1'b0;
                                we_o <= 1'b0;
                                padr_o <= 32'hFFFFFFF8;
                                padr_o <= 32'hFFFFFFF8;
                                prv_o <= 1'b1;
                                prv_o <= 1'b1;
                        end
                        end
                        goto(S_ACK);
                        goto(S_ACK);
                end
                end
        end
        end
        else begin
        else begin
                pt_ad <= {pt_ad+8'd65};
                pt_ad <= {pt_ad+8'd65};
                goto(S_CMP4);
                goto(S_CMP4);
        end
        end
 
 
// Wait a clock cycle for a page fault to register.
// Wait a clock cycle for a page fault to register.
S_WAIT1:
S_WAIT1:
 
        if (!ack_i)
        goto(S_IDLE);
        goto(S_IDLE);
 
 
S_ACK:
S_ACK:
        if (ack_i) begin
        if (ack_i) begin
                if (cti_i==3'b000 || cti_i==3'b111) begin
                if (cti_i==3'b000 || cti_i==3'b111) begin
                        cyc_o <= 1'b0;
                        cyc_o <= 1'b0;
                        we_o <= 1'b0;
                        we_o <= 1'b0;
                        goto(S_WAIT1);
                        goto(S_WAIT1);
                end
                end
        end
        end
 
 
endcase
endcase
end
end
`endif
`endif
 
 
task goto;
task goto;
input [3:0] nst;
input [3:0] nst;
begin
begin
        state <= nst;
        state <= nst;
end
end
endtask
endtask
 
 
endmodule
endmodule
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.