437 lines
18 KiB
Verilog
437 lines
18 KiB
Verilog
`default_nettype wire
|
||
|
||
module axi_ctrl_v5
|
||
#(
|
||
parameter TAG_WD = 21,
|
||
parameter INDEX_WD = 64,
|
||
parameter CACHELINE_WD = 512,
|
||
parameter STAGE_WD = 12
|
||
)
|
||
(
|
||
input clk,
|
||
input reset,
|
||
|
||
// icache interface
|
||
input icache_re, // miss
|
||
input [31 :0] icache_raddr, // miss_addr
|
||
output reg [CACHELINE_WD -1:0] icache_cacheline_new,
|
||
|
||
input icache_we, // we_back
|
||
input [31 :0] icache_waddr, // waddr
|
||
input [CACHELINE_WD -1:0] icache_cacheline_old, // wback
|
||
|
||
output reg icache_refresh,
|
||
|
||
// dcache interface
|
||
input dcache_re, // miss
|
||
input [31 :0] dcache_raddr, // miss_addr
|
||
output reg [CACHELINE_WD -1:0] dcache_cacheline_new,
|
||
|
||
input dcache_we, // we_back
|
||
input [31 :0] dcache_waddr, // waddr
|
||
input [CACHELINE_WD -1:0] dcache_cacheline_old, // wback
|
||
|
||
output reg dcache_refresh, // fin
|
||
|
||
// uncache interface
|
||
input uncache_en,
|
||
input [3 :0] uncache_we,
|
||
input [31 :0] uncache_addr,
|
||
input [31 :0] uncache_wdata,
|
||
output reg [31 :0] uncache_rdata,
|
||
output reg uncache_refresh,
|
||
|
||
//总线侧接å<C2A5>?
|
||
//读地å<C2B0>?通é<C5A1>“ä¿¡å<C2A1>·
|
||
output reg [3 :0] arid, //读地å<C2B0>?ID,用æ<C2A8>¥æ ‡å¿—一组写信å<C2A1>·
|
||
output reg [31:0] araddr, //读地å<C2B0>?,给出一次写çª<C3A7>å<EFBFBD>‘ä¼ è¾“çš„è¯»åœ°å<C2B0>€
|
||
output reg [3 :0] arlen, //çª<C3A7>å<EFBFBD>‘长度,给出çª<C3A7>å<EFBFBD>‘ä¼ è¾“çš„æ¬¡æ•°
|
||
output reg [2 :0] arsize, //çª<C3A7>å<EFBFBD>‘大å°<C3A5>,给出æ¯<C3A6>次çª<C3A7>å<EFBFBD>‘ä¼ è¾“çš„å—节æ•?
|
||
output reg [1 :0] arburst, //çª<C3A7>å<EFBFBD>‘类型
|
||
output reg [1 :0] arlock, //总线é”<C3A9>ä¿¡å<C2A1>·ï¼Œå<C592>¯æ<C2AF><C3A6>ä¾›æ“<C3A6>作的原å<C3A5>æ€?
|
||
output reg [3 :0] arcache, //内å˜ç±»åž‹ï¼Œè¡¨æ˜Žä¸€æ¬¡ä¼ è¾“æ˜¯æ€Žæ ·é€šè¿‡ç³»ç»Ÿçš?
|
||
output reg [2 :0] arprot, //ä¿<C3A4>æŠ¤ç±»åž‹ï¼Œè¡¨æ˜Žä¸€æ¬¡ä¼ è¾“çš„ç‰¹æ<C2B9>ƒçº§å<C2A7>Šå®‰å…¨ç‰çº§
|
||
output reg arvalid, //有效信å<C2A1>·ï¼Œè¡¨æ˜Žæ¤é€šé<C5A1>“的地å<C2B0>?控制信å<C2A1>·æœ‰æ•ˆ
|
||
input arready, //表明"ä»?"å<>¯ä»¥æŽ¥æ”¶åœ°å<C2B0>€å’Œå¯¹åº”的控制信å<C2A1>·
|
||
//读数æ<C2B0>®é?šé<C5A1>“ä¿¡å<C2A1>·
|
||
input [3 :0] rid, //读ID tag
|
||
input [31:0] rdata, //读数æ<C2B0>?
|
||
input [1 :0] rresp, //读å“<C3A5>åº”ï¼Œè¡¨æ˜Žè¯»ä¼ è¾“çš„çŠ¶æ??
|
||
input rlast, //表明读çª<C3A7>å<EFBFBD>‘çš„æœ?å<>Žä¸€æ¬¡ä¼ è¾?
|
||
input rvalid, //表明æ¤é?šé<C5A1>“ä¿¡å<C2A1>·æœ‰æ•ˆ
|
||
output reg rready, //表明主机能够接收读数æ<C2B0>®å’Œå“<C3A5>应信æ<C2A1>¯
|
||
|
||
//写地å<C2B0>?通é<C5A1>“ä¿¡å<C2A1>·
|
||
output reg [3 :0] awid, //写地å<C2B0>?ID,用æ<C2A8>¥æ ‡å¿—一组写信å<C2A1>·
|
||
output reg [31:0] awaddr, //写地å<C2B0>?,给出一次写çª<C3A7>å<EFBFBD>‘ä¼ è¾“çš„å†™åœ°å<C2B0>€
|
||
output reg [3 :0] awlen, //çª<C3A7>å<EFBFBD>‘长度,给出çª<C3A7>å<EFBFBD>‘ä¼ è¾“çš„æ¬¡æ•°
|
||
output reg [2 :0] awsize, //çª<C3A7>å<EFBFBD>‘大å°<C3A5>,给出æ¯<C3A6>次çª<C3A7>å<EFBFBD>‘ä¼ è¾“çš„å—节æ•?
|
||
output reg [1 :0] awburst, //çª<C3A7>å<EFBFBD>‘类型
|
||
output reg [1 :0] awlock, //总线é”<C3A9>ä¿¡å<C2A1>·ï¼Œå<C592>¯æ<C2AF><C3A6>ä¾›æ“<C3A6>作的原å<C3A5>æ€?
|
||
output reg [3 :0] awcache, //内å˜ç±»åž‹ï¼Œè¡¨æ˜Žä¸€æ¬¡ä¼ è¾“æ˜¯æ€Žæ ·é€šè¿‡ç³»ç»Ÿçš?
|
||
output reg [2 :0] awprot, //ä¿<C3A4>æŠ¤ç±»åž‹ï¼Œè¡¨æ˜Žä¸€æ¬¡ä¼ è¾“çš„ç‰¹æ<C2B9>ƒçº§å<C2A7>Šå®‰å…¨ç‰çº§
|
||
output reg awvalid, //有效信å<C2A1>·ï¼Œè¡¨æ˜Žæ¤é€šé<C5A1>“的地å<C2B0>?控制信å<C2A1>·æœ‰æ•ˆ
|
||
input awready, //表明"ä»?"å<>¯ä»¥æŽ¥æ”¶åœ°å<C2B0>€å’Œå¯¹åº”的控制信å<C2A1>·
|
||
//写数æ<C2B0>®é?šé<C5A1>“ä¿¡å<C2A1>·
|
||
output reg [3 :0] wid, //ä¸?æ¬¡å†™ä¼ è¾“çš„ID tag
|
||
output reg [31:0] wdata, //写数æ<C2B0>?
|
||
output reg [3 :0] wstrb, //写数æ<C2B0>®æœ‰æ•ˆçš„å—节线,用æ<C2A8>¥è¡¨æ˜Žå“?8bitsæ•°æ<C2B0>®æ˜¯æœ‰æ•ˆçš„
|
||
output reg wlast, //è¡¨æ˜Žæ¤æ¬¡ä¼ 输是最å<E282AC>Žä¸€ä¸ªçª<C3A7>å<EFBFBD>‘ä¼ è¾?
|
||
output reg wvalid, //å†™æœ‰æ•ˆï¼Œè¡¨æ˜Žæ¤æ¬¡å†™æœ‰æ•?
|
||
input wready, //表明从机å<C2BA>¯ä»¥æŽ¥æ”¶å†™æ•°æ<C2B0>?
|
||
//写å“<C3A5>应é?šé<C5A1>“ä¿¡å<C2A1>·
|
||
input [3 :0] bid, //写å“<C3A5>应ID tag
|
||
input [1 :0] bresp, //写å“<C3A5>åº”ï¼Œè¡¨æ˜Žå†™ä¼ è¾“çš„çŠ¶æ?? 00为æ£å¸¸ï¼Œå½“ç„¶å<C2B6>¯ä»¥ä¸<C3A4>ç<EFBFBD>†ä¼?
|
||
input bvalid, //写å“<C3A5>应有æ•?
|
||
output reg bready //表明主机能够接收写å“<C3A5>åº?
|
||
|
||
);
|
||
reg [CACHELINE_WD -1:0] icache_rdata_buffer;
|
||
reg [CACHELINE_WD -1:0] icache_wdata_buffer;
|
||
reg [CACHELINE_WD -1:0] dcache_rdata_buffer;
|
||
reg [CACHELINE_WD -1:0] dcache_wdata_buffer;
|
||
reg [31 :0] icache_raddr_buffer;
|
||
reg [31 :0] icache_waddr_buffer;
|
||
reg [31 :0] dcache_raddr_buffer;
|
||
reg [31 :0] dcache_waddr_buffer;
|
||
reg [3 :0] icache_offset;
|
||
reg [3 :0] dcache_offset;
|
||
reg [3 :0] dcache_offset_w;
|
||
reg icache_re_buffer;
|
||
reg dcache_re_buffer;
|
||
reg icache_we_buffer;
|
||
reg dcache_we_buffer;
|
||
|
||
reg uncache_en_buffer;
|
||
reg [3 :0] uncache_we_buffer;
|
||
reg [31 :0] uncache_addr_buffer;
|
||
reg [31 :0] uncache_wdata_buffer;
|
||
reg [31 :0] uncache_rdata_buffer;
|
||
|
||
reg [STAGE_WD -1:0] stage;
|
||
reg [STAGE_WD -1:0] stage_w;
|
||
|
||
always @(posedge clk) begin
|
||
if(reset) begin
|
||
arid <= 4'b0000;
|
||
araddr <= 32'b0;
|
||
arlen <= 4'b0000;
|
||
arsize <= 3'b010;
|
||
arburst <= 2'b01;
|
||
arlock <= 2'b00;
|
||
arcache <= 4'b0000;
|
||
arprot <= 3'b000;
|
||
arvalid <= 1'b0;
|
||
|
||
rready <= 1'b0;
|
||
|
||
stage <= {{(STAGE_WD-1){1'b0}}, 1'b1};
|
||
|
||
icache_refresh <= 0;
|
||
dcache_refresh <= 0;
|
||
icache_cacheline_new <= 0;
|
||
dcache_cacheline_new <= 0;
|
||
|
||
uncache_refresh <= 1'b0;
|
||
uncache_rdata <= 32'b0;
|
||
end
|
||
else begin
|
||
case (1'b1)
|
||
stage[0]: begin
|
||
icache_refresh <= 1'b0;
|
||
dcache_refresh <= 1'b0;
|
||
uncache_refresh <= 1'b0;
|
||
|
||
icache_re_buffer <= icache_re;
|
||
icache_raddr_buffer <= icache_raddr;
|
||
icache_we_buffer <= icache_we;
|
||
icache_waddr_buffer <= icache_waddr;
|
||
|
||
dcache_re_buffer <= dcache_re;
|
||
dcache_raddr_buffer <= dcache_raddr;
|
||
dcache_we_buffer <= dcache_we;
|
||
dcache_waddr_buffer <= dcache_waddr;
|
||
|
||
uncache_en_buffer <= uncache_en;
|
||
uncache_we_buffer <= uncache_we;
|
||
uncache_addr_buffer <= uncache_addr;
|
||
uncache_wdata_buffer <= uncache_wdata;
|
||
|
||
if (dcache_we|(uncache_en&((|uncache_we)))) begin
|
||
stage <= stage << 1;
|
||
end
|
||
else if (icache_re|dcache_re|(uncache_en&~(|uncache_we))) begin
|
||
stage <= stage << 2;
|
||
end
|
||
end
|
||
stage[1]: begin
|
||
icache_wdata_buffer <= icache_cacheline_old;
|
||
dcache_wdata_buffer <= dcache_cacheline_old;
|
||
if (icache_re_buffer|dcache_re_buffer|(uncache_en_buffer&~(|uncache_we_buffer))) begin
|
||
stage <= stage << 1;
|
||
end
|
||
else begin
|
||
stage <= {1'b0,1'b1,10'b0};
|
||
end
|
||
end
|
||
stage[2]:begin
|
||
if (icache_re_buffer) begin
|
||
arid <= 4'b0;
|
||
araddr <= icache_raddr_buffer;
|
||
arlen <= 4'hf;
|
||
arsize <= 3'b010;
|
||
arvalid <= 1'b1;
|
||
|
||
stage <= stage << 1;
|
||
end
|
||
else begin
|
||
stage <= stage << 3;
|
||
end
|
||
end
|
||
stage[3]:begin
|
||
if (arready) begin
|
||
arvalid <= 1'b0;
|
||
araddr <= 32'b0;
|
||
rready <= 1'b1;
|
||
icache_offset <= 4'd0;
|
||
stage <= stage << 1;
|
||
end
|
||
end
|
||
stage[4]:begin
|
||
if (!rlast&rvalid) begin
|
||
icache_rdata_buffer[icache_offset*32+:32] <= rdata;
|
||
icache_offset <= icache_offset + 1'b1;
|
||
end
|
||
else if(rlast&rvalid) begin
|
||
icache_rdata_buffer[icache_offset*32+:32] <= rdata;
|
||
rready <= 1'b0;
|
||
stage <= stage << 1;
|
||
end
|
||
end
|
||
stage[5]:begin
|
||
if (dcache_re_buffer) begin
|
||
arid <= 4'b1;
|
||
araddr <= dcache_raddr_buffer;
|
||
arlen <= 4'hf;
|
||
arsize <= 3'b010;
|
||
arvalid <= 1'b1;
|
||
|
||
stage <= stage << 1;
|
||
end
|
||
else if (uncache_en_buffer&~(|uncache_we_buffer)) begin
|
||
arid <= 4'b1;
|
||
araddr <= uncache_addr_buffer;
|
||
arlen <= 4'b0;
|
||
arsize <= 3'b010;
|
||
arvalid <= 1'b1;
|
||
stage <= stage << 3;
|
||
end
|
||
else begin
|
||
stage <= {1'b0,1'b1,10'b0};
|
||
end
|
||
end
|
||
stage[6]:begin
|
||
if (arready) begin
|
||
arvalid <= 1'b0;
|
||
araddr <= 32'b0;
|
||
rready <= 1'b1;
|
||
dcache_offset <= 4'd0;
|
||
stage <= stage << 1;
|
||
end
|
||
end
|
||
stage[7]:begin
|
||
if (!rlast&rvalid) begin
|
||
dcache_rdata_buffer[dcache_offset*32+:32] <= rdata;
|
||
dcache_offset <= dcache_offset + 1'b1;
|
||
end
|
||
else if (rlast&rvalid) begin
|
||
dcache_rdata_buffer[dcache_offset*32+:32] <= rdata;
|
||
rready <= 1'b0;
|
||
stage <= {1'b0,1'b1,10'b0};
|
||
end
|
||
end
|
||
stage[8]:begin
|
||
if (arready) begin
|
||
arvalid <= 1'b0;
|
||
araddr <= 32'b0;
|
||
rready <= 1'b1;
|
||
stage <= stage << 1;
|
||
end
|
||
end
|
||
stage[9]:begin
|
||
if (rvalid) begin
|
||
uncache_rdata_buffer <= rdata;
|
||
rready <= 1'b0;
|
||
stage <= {1'b0,1'b1,10'b0};
|
||
end
|
||
end
|
||
stage[10]:begin
|
||
if (stage_w[10]|stage_w[0]) begin
|
||
stage <= stage << 1;
|
||
end
|
||
end
|
||
stage[11]:begin
|
||
if (icache_re_buffer) begin
|
||
icache_refresh <= 1'b1;
|
||
icache_cacheline_new <= icache_rdata_buffer;
|
||
end
|
||
if (dcache_re_buffer) begin
|
||
dcache_refresh <= 1'b1;
|
||
dcache_cacheline_new <= dcache_rdata_buffer;
|
||
end
|
||
if (uncache_en_buffer) begin
|
||
uncache_refresh <= 1'b1;
|
||
uncache_rdata <= uncache_rdata_buffer;
|
||
end
|
||
stage <= 0;
|
||
end
|
||
default:begin
|
||
stage <= {{(STAGE_WD-1){1'b0}}, 1'b1};
|
||
icache_refresh <= 1'b0;
|
||
dcache_refresh <= 1'b0;
|
||
uncache_refresh <= 1'b0;
|
||
end
|
||
endcase
|
||
end
|
||
end
|
||
|
||
always @ (posedge clk) begin
|
||
if (reset) begin
|
||
awid <= 4'b0001;
|
||
awaddr <= 32'b0;
|
||
awlen <= 4'b0000;
|
||
awsize <= 3'b010;
|
||
awburst <= 2'b01;
|
||
awlock <= 2'b00;
|
||
awcache <= 4'b0000;
|
||
awprot <= 3'b000;
|
||
awvalid <= 1'b0;
|
||
|
||
wid <= 4'b0001;
|
||
wdata <= 32'b0;
|
||
wstrb <= 4'b0000;
|
||
wlast <= 1'b0;
|
||
wvalid <= 1'b0;
|
||
|
||
bready <= 1'b0;
|
||
|
||
stage_w <= {{(STAGE_WD-1){1'b0}}, 1'b1};
|
||
end
|
||
else begin
|
||
case (1'b1)
|
||
stage_w[0]:begin
|
||
if (stage[1]) begin
|
||
if (dcache_we_buffer) begin
|
||
awid <= 4'b1;
|
||
awaddr <= dcache_waddr_buffer;
|
||
awlen <= 4'hf;
|
||
awsize <= 3'b010;
|
||
awvalid <= 1'b1;
|
||
wstrb <= 4'b1111;
|
||
wlast <= 1'b0;
|
||
bready <= 1'b1;
|
||
dcache_offset_w <= 4'b0;
|
||
stage_w <= stage_w << 1;
|
||
end
|
||
else if (|uncache_we_buffer) begin // write
|
||
awid <= 4'b1;
|
||
awaddr <= uncache_addr_buffer;
|
||
awlen <= 4'b0;
|
||
case (uncache_we_buffer)
|
||
4'b0001,4'b0010,4'b0100,4'b1000:begin
|
||
awsize <= 3'b000;
|
||
wstrb <= uncache_we_buffer;
|
||
end
|
||
4'b0011,4'b1100:begin
|
||
awsize <= 3'b001;
|
||
wstrb <= uncache_we_buffer;
|
||
end
|
||
4'b1111:begin
|
||
awsize <= 3'b010;
|
||
wstrb <= uncache_we_buffer;
|
||
end
|
||
default:begin
|
||
awsize <= 3'b010;
|
||
wstrb <= uncache_we_buffer;
|
||
end
|
||
endcase
|
||
awvalid <= 1'b1;
|
||
wlast <= 1'b0;
|
||
bready <= 1'b1;
|
||
stage_w <= stage_w << 4;
|
||
end
|
||
end
|
||
end
|
||
stage_w[1]:begin
|
||
if (awready) begin
|
||
awvalid <= 1'b0;
|
||
awaddr <= 32'b0;
|
||
wdata <= dcache_wdata_buffer[dcache_offset_w*32+:32];
|
||
wvalid <= 1'b1;
|
||
wlast <= dcache_offset_w == 4'b1111 ? 1'b1 : 1'b0;
|
||
dcache_offset_w <= dcache_offset_w + 1'b1;
|
||
if (dcache_offset_w == 4'b1111) begin
|
||
stage_w <= stage_w << 1;
|
||
end
|
||
end
|
||
else if (wready) begin
|
||
wdata <= dcache_wdata_buffer[dcache_offset_w*32+:32];
|
||
wvalid <= 1'b1;
|
||
wlast <= dcache_offset_w == 4'b1111 ? 1'b1 : 1'b0;
|
||
dcache_offset_w <= dcache_offset_w + 1'b1;
|
||
if (dcache_offset_w == 4'b1111) begin
|
||
stage_w <= stage_w << 1;
|
||
end
|
||
end
|
||
end
|
||
stage_w[2]:begin
|
||
if (wready) begin
|
||
wdata <= 32'b0;
|
||
wvalid <= 1'b0;
|
||
wlast <= 1'b0;
|
||
stage_w <= stage_w << 1;
|
||
end
|
||
end
|
||
stage_w[3]:begin
|
||
if (bvalid) begin
|
||
bready <= 1'b0;
|
||
stage_w <= {1'b0,1'b1,{10{1'b0}}};
|
||
end
|
||
end
|
||
stage_w[4]:begin
|
||
if (awready) begin
|
||
awvalid <= 1'b0;
|
||
awaddr <= 32'b0;
|
||
wdata <= uncache_wdata_buffer;
|
||
wvalid <= 1'b1;
|
||
wlast <= 1'b1;
|
||
stage_w <= stage_w << 1;
|
||
end
|
||
end
|
||
stage_w[5]:begin
|
||
if (wready) begin
|
||
wdata <= 32'b0;
|
||
wvalid <= 1'b0;
|
||
wlast <= 1'b0;
|
||
stage_w <= stage_w << 1;
|
||
end
|
||
end
|
||
stage_w[6]:begin
|
||
if (bvalid) begin
|
||
bready <= 1'b0;
|
||
stage_w <= {1'b0,1'b1,{10{1'b0}}};
|
||
end
|
||
end
|
||
stage_w[10]:begin
|
||
if (stage[11]) begin
|
||
stage_w <= {{(STAGE_WD-1){1'b0}}, 1'b1};
|
||
end
|
||
end
|
||
default:begin
|
||
stage_w <= {{(STAGE_WD-1){1'b0}}, 1'b1};
|
||
end
|
||
endcase
|
||
end
|
||
end
|
||
|
||
endmodule |