Commit 3ffdb903 by Zhengyue Zhao

Add new file

parent da4c4a53
module RISCV_mmu_for_val(
clock, reset,
axi_read_data, axi_read_data_valid, axi_write_data_bvalid,
satp, mstatus, sstatus,
instruction_type, this_priviledge,
logic_axi_read_data_address, logic_axi_write_data_address,
logic_axi_write_data,
logic_axi_read_data_address_valid, logic_axi_write_data_valid,
axi_read_data_address, axi_read_data_address_valid,
axi_write_data_address, axi_write_data, axi_write_data_valid,
store_data_size_in, store_data_size,
logic_axi_read_data, logic_axi_write_data_bvalid, logic_axi_read_data_valid,
logic_axi_read_data_page_fault, logic_axi_write_data_page_fault
);
input clock, reset;
input [31:0] axi_read_data;
input axi_read_data_valid;
input axi_write_data_bvalid;
input [31:0] satp;
input [31:0] mstatus;
input [31:0] sstatus;
input [1:0] instruction_type;
input [1:0] this_priviledge;
input [31:0] logic_axi_read_data_address;
input [31:0] logic_axi_write_data_address;
input [31:0] logic_axi_write_data;
input logic_axi_read_data_address_valid;
input logic_axi_write_data_valid;
input [1:0] store_data_size_in;
output reg [31:0] axi_read_data_address;
output reg axi_read_data_address_valid;
output reg [31:0] axi_write_data_address;
output reg [31:0] axi_write_data;
output reg axi_write_data_valid;
output [1:0] store_data_size = store_data_size_in;
output reg [31:0] logic_axi_read_data;
output reg logic_axi_write_data_bvalid;
output reg logic_axi_read_data_valid;
output reg logic_axi_read_data_page_fault;
output reg logic_axi_write_data_page_fault;
/////////////////////////////////////////////////////
wire mmu_on = satp[31];
wire mxr = mstatus[19];
wire sum = mstatus[18];
wire mprv = mstatus[17];
reg [1:0] page_table_ply;
integer v=0;
integer r=1;
integer w=2;
integer x=3;
integer u=4;
integer g=5;
integer a=6;
integer d=7;
///////////////////// PTE 1 /////////////////////////
reg [31:0] read_PTE_1_address;
reg read_PTE_1_address_valid;
reg [31:0] read_PTE_1_data;
reg read_PTE_1_data_valid;
reg read_PTE_2_address_fault;
always@(posedge clock)
begin
if(!reset)//initialization
begin
read_PTE_1_address <= 32'b0;
read_PTE_1_address_valid <= 1'b0;
read_PTE_1_data <= 32'b0;
read_PTE_1_data_valid <=1'b0;
page_table_ply <= 2'b0;
read_PTE_2_address_fault <= 1'b0;
end
else
begin
//conputing PTE 1 address
//case 1: load address
if(!read_PTE_1_address_valid && logic_axi_read_data_address_valid)
begin
read_PTE_1_address <= {satp[19:0],logic_axi_read_data_address[31:22],2'b0};
read_PTE_1_address_valid <= 1'b1;
end
else if(!read_PTE_1_address_valid && logic_axi_write_data_valid)
begin
read_PTE_1_address <= {satp[19:0],logic_axi_write_data_address[31:22],2'b0};
read_PTE_1_address_valid <= 1'b1;
end
else if(read_PTE_1_address_valid && read_PTE_1_data_valid)
begin
read_PTE_1_address <= 32'b0;
read_PTE_1_address_valid <= 1'b0;
end
else
begin
read_PTE_1_address <= read_PTE_1_address;
read_PTE_1_address_valid <= read_PTE_1_address_valid;
end
if(!read_PTE_1_data_valid && read_PTE_1_address_valid && axi_read_data_valid)
begin
read_PTE_1_data <= axi_read_data;
read_PTE_1_data_valid <= 1'b1;
if(read_PTE_1_data[v] && (!(read_PTE_1_data[r] || read_PTE_1_data[x] || read_PTE_1_data[w])))
page_table_ply <= 2'b01;//PTE 1 is a leaf PTE
else
page_table_ply <= 2'b10;//PTE 1 is a pointer PTE
//set page fault
if(!read_PTE_1_data[v])
read_PTE_2_address_fault <= 1'b1;
else if(read_PTE_1_data[w] && !read_PTE_1_data[r])
read_PTE_2_address_fault <= 1'b1;
else if((page_table_ply==2'b01)&&!(
(instruction_type[0]&&read_PTE_1_data[r])
||(instruction_type[1]&&read_PTE_1_data[w])
||(instruction_type==2'b0&&read_PTE_1_data[x])
||(instruction_type[0]&&mxr&&read_PTE_1_data[x])
))
read_PTE_2_address_fault <= 1'b1;
else if((page_table_ply==2'b01)
&&read_PTE_1_data[u]&&!sum
&&(this_priviledge==2'b01)
&&!sstatus[18]
)
read_PTE_2_address_fault <= 1'b1;
else if((page_table_ply==2'b01)
&&((!read_PTE_1_data[a])||(instruction_type[1]&&!read_PTE_1_data[d]))
)
read_PTE_2_address_fault <= 1'b1;
else
read_PTE_2_address_fault <= 1'b0;
end
else if(read_PTE_1_data_valid && read_PTE_1_address_valid)
begin
read_PTE_1_data <= 32'b0;
read_PTE_1_data_valid <= 1'b0;
read_PTE_2_address_fault <= 1'b0;
end
else
begin
read_PTE_1_data <= read_PTE_1_data;
read_PTE_1_data_valid <= read_PTE_1_data_valid;
read_PTE_2_address_fault <= read_PTE_2_address_fault;
end
end
end
////////////////////// PTE 2 ////////////////////////////////
reg [31:0] read_PTE_2_address;
reg read_PTE_2_address_valid;
reg [31:0] read_PTE_2_data;
reg read_PTE_2_data_valid;
reg read_physical_address_fault;
always@(posedge clock)
begin
if(!reset)//initialization
begin
read_PTE_2_address <= 32'b0;
read_PTE_2_address_valid <= 1'b0;
read_PTE_2_data <= 32'b0;
read_PTE_2_data_valid <=1'b0;
read_physical_address_fault <= 1'b0;
end
else if(page_table_ply == 2'b10)
begin
//conputing PTE 2 address
//case 1: load address
if(!read_PTE_2_address_valid && logic_axi_read_data_address_valid)
begin
read_PTE_2_address <= {read_PTE_1_data[29:10],logic_axi_read_data_address[21:12],2'b0};
read_PTE_2_address_valid <= 1'b1;
end
else if(!read_PTE_2_address_valid && logic_axi_write_data_valid)
begin
read_PTE_2_address <= {read_PTE_1_data[29:10],logic_axi_write_data_address[21:12],2'b0};
read_PTE_2_address_valid <= 1'b1;
end
else if(read_PTE_2_address_valid && read_PTE_2_data_valid)
begin
read_PTE_2_address <= 32'b0;
read_PTE_2_address_valid <= 1'b0;
end
else
begin
read_PTE_2_address <= read_PTE_2_address;
read_PTE_2_address_valid <= read_PTE_2_address_valid;
end
if(!read_PTE_2_data_valid && read_PTE_2_address_valid && axi_read_data_valid)
begin
read_PTE_2_data <= axi_read_data;
read_PTE_2_data_valid <= 1'b1;
//set page fault
if(!read_PTE_2_data[v])
read_physical_address_fault <= 1'b1;
else if(read_PTE_2_data[w] && !read_PTE_2_data[r])
read_physical_address_fault <= 1'b1;
else if(!((instruction_type[0]&&read_PTE_2_data[r])
||(instruction_type[1]&&read_PTE_2_data[w])
||(instruction_type==2'b0&&read_PTE_2_data[x])
||(instruction_type[0]&&mxr&&read_PTE_2_data[x])
))
read_physical_address_fault <= 1'b1;
else if(read_PTE_2_data[u]&&!sum
&&(this_priviledge==2'b01)
&&!sstatus[18]
)
read_physical_address_fault <= 1'b1;
else if(((!read_PTE_2_data[a])
||(instruction_type[1]&&!read_PTE_2_data[d]))
)
read_physical_address_fault <= 1'b1;
else
read_physical_address_fault <= 1'b0;
end
else if(read_PTE_2_data_valid && read_PTE_2_address_valid)
begin
read_PTE_2_data <= 32'b0;
read_PTE_2_data_valid <= 1'b0;
read_physical_address_fault <= 1'b0;
end
else
begin
read_PTE_2_data <= read_PTE_2_data;
read_PTE_2_data_valid <= read_PTE_2_data_valid;
read_physical_address_fault <= read_physical_address_fault;
end
end
end
//////////////////////// physical address ///////////////////////
reg [31:0] read_physical_address;
reg read_physical_address_valid;
// reg [31:0] write_physical_address;
// reg write_physical_address_valid;
//physical data
reg [31:0] read_physical_data;
reg read_physical_data_valid;
// reg [31:0] write_physical_data;
// reg write_physical_data_valid;
//write physical bvalid
reg write_physical_data_bvalid;
always@(posedge clock)
begin
if(!reset)//initialization
begin
read_physical_address <= 32'b0;
read_physical_address_valid <= 1'b0;
read_physical_data <= 32'b0;
read_physical_data_valid <= 1'b0;
write_physical_data_bvalid <= 1'B0;
end
else
begin
//conputing physical address
//case 1: load address
if(!read_physical_address_valid && read_PTE_2_data_valid && logic_axi_read_data_address_valid && (page_table_ply==2'b10))
begin
read_physical_address <= {read_PTE_2_data[29:10],logic_axi_read_data_address[11:0]};
read_physical_address_valid <=1'b1;
end
else if(!read_physical_address_valid && read_PTE_2_data_valid && logic_axi_read_data_address_valid && (page_table_ply==2'b01))
begin
read_physical_address <= {read_PTE_2_data[29:20],logic_axi_read_data_address[21:0]};
read_physical_address_valid <=1'b1;
end
else if(!read_physical_address_valid && read_PTE_2_data_valid && logic_axi_write_data_valid && (page_table_ply==2'b10))
begin
read_physical_address <= {read_PTE_2_data[29:10],logic_axi_write_data_address[11:0]};
read_physical_address_valid <=1'b1;
end
else if(!read_physical_address_valid && read_PTE_2_data_valid && logic_axi_write_data_valid && (page_table_ply==2'b01))
begin
read_physical_address <= {read_PTE_2_data[29:20],logic_axi_write_data_address[21:0]};
read_physical_address_valid <=1'b1;
end
else if(read_physical_address_valid && read_physical_data_valid)
begin
read_physical_address <= 32'b0;
read_physical_address_valid <= 1'b0;
end
else
begin
read_physical_address <= read_physical_address;
read_physical_address_valid <= read_physical_address_valid;
end
if(!read_physical_data_valid && read_physical_address_valid && axi_read_data_valid)
begin
read_physical_data <= axi_read_data;
read_physical_data_valid <= 1'b1;
end
else if(read_physical_data_valid && read_physical_address_valid)
begin
read_physical_data <= 32'b0;
read_physical_data_valid <= 1'b0;
end
else
begin
read_physical_data <= read_physical_data;
read_physical_data_valid <= read_physical_data_valid;
end
if(!write_physical_data_bvalid && read_physical_address_valid && axi_write_data_bvalid)
write_physical_data_bvalid <= 1'b1;
else if(write_physical_data_bvalid && read_physical_address_valid)
write_physical_data_bvalid <= 1'b1;
else
write_physical_data_bvalid <= write_physical_data_bvalid;
end
end
//////////////////////////// set address ////////////////////////
always@(posedge clock)
begin
if(!reset)
begin
axi_read_data_address <= 32'b0;
axi_read_data_address_valid <= 1'b0;
axi_write_data_address <= 32'b0;
axi_write_data <= 32'b0;
axi_write_data_valid <= 1'b0;
end
else
begin
//case 1: load address
if(!mmu_on)
begin
axi_read_data_address <= logic_axi_read_data_address;
axi_read_data_address_valid <=logic_axi_read_data_address_valid;
end
else if(mmu_on && read_PTE_1_address_valid)
begin
axi_read_data_address <= read_PTE_1_address;
axi_read_data_address_valid <= 1'b1;
end
else if(mmu_on && read_PTE_2_address_valid)
begin
axi_read_data_address <= read_PTE_2_address;
axi_read_data_address_valid <= 1'b1;
end
else if(mmu_on && read_physical_address_valid)
begin
axi_read_data_address <= read_physical_address;
axi_read_data_address_valid <= 1'b1;
end
else if(axi_read_data_address_valid && (read_PTE_1_data_valid || read_PTE_2_data_valid || read_physical_data_valid))
begin
axi_read_data_address <= 32'b0;
axi_read_data_address_valid <= 1'b0;
end
else
begin
axi_read_data_address <= axi_read_data_address;
axi_read_data_address_valid <=axi_read_data_address_valid;
end
//case 2: store address
if(!mmu_on)
begin
axi_write_data_address <= logic_axi_write_data_address;
axi_write_data <= logic_axi_write_data;
axi_write_data_valid <= logic_axi_write_data_valid;
end
else if(mmu_on && read_physical_address_valid && !axi_write_data_valid)
begin
axi_write_data_address <= read_physical_address;
axi_write_data <= logic_axi_write_data;
axi_write_data_valid <= 1'b1;
end
else if(axi_write_data_valid && write_physical_data_bvalid)
begin
axi_write_data_address <= 32'b0;
axi_write_data <= 32'b0;
axi_write_data_valid <= 1'b0;
end
else
begin
axi_write_data_address <= axi_write_data_address;
axi_write_data <=axi_write_data;
axi_write_data_valid <=axi_write_data_valid;
end
end
end
//////////////////////// read data /////////////////////////////
always@(posedge clock)
begin
if(!reset)
begin
logic_axi_read_data <= 32'b0;
logic_axi_read_data_valid <= 1'b0;
logic_axi_write_data_bvalid <= 1'b0;
end
else
begin
if(!mmu_on && logic_axi_read_data_address_valid)
begin
logic_axi_read_data <= axi_read_data;
logic_axi_read_data_valid <= axi_read_data_valid;
end
else if(read_physical_address_valid && read_physical_data_valid && logic_axi_read_data_address_valid)
begin
logic_axi_read_data <= axi_read_data;
logic_axi_read_data_valid <= axi_read_data_valid;
end
else if(!logic_axi_read_data_address_valid || logic_axi_write_data_page_fault || logic_axi_read_data_page_fault)
begin
logic_axi_read_data <= 1'b0;
logic_axi_read_data_valid <= 1'b0;
end
else
begin
logic_axi_read_data <= logic_axi_read_data ;
logic_axi_read_data_valid <= logic_axi_read_data_valid ;
end
if(!mmu_on && logic_axi_write_data_valid)
logic_axi_write_data_bvalid <= axi_write_data_bvalid;
else if(read_physical_address_valid && write_physical_data_bvalid && logic_axi_write_data_valid)
logic_axi_write_data_bvalid <= axi_write_data_bvalid;
else if(!logic_axi_write_data_valid || logic_axi_write_data_page_fault || logic_axi_read_data_page_fault)
logic_axi_write_data_bvalid <= 1'b0;
else
logic_axi_write_data_bvalid <= logic_axi_write_data_bvalid;
end
end
////////////////////////////// page fault ////////////////////////////
always@(posedge clock)
begin
if(!reset)
begin
if(!mmu_on)
logic_axi_write_data_page_fault <= 1'b0;
else if(mmu_on && logic_axi_write_data_valid && (read_PTE_2_address_fault || read_physical_address_fault))
logic_axi_write_data_page_fault <= 1'b1;
else if(logic_axi_write_data_page_fault && logic_axi_write_data_valid)
logic_axi_write_data_page_fault <= 1'b0;
else
logic_axi_write_data_page_fault <= logic_axi_write_data_page_fault;
if(!mmu_on)
logic_axi_read_data_page_fault <= 1'b0;
else if(mmu_on && logic_axi_read_data_valid && (read_PTE_2_address_fault || read_physical_address_fault))
logic_axi_read_data_page_fault <= 1'b1;
else if(logic_axi_read_data_page_fault && logic_axi_read_data_valid)
logic_axi_read_data_page_fault <= 1'b0;
else
logic_axi_read_data_page_fault <= logic_axi_write_data_page_fault;
end
end
endmodule
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment