301 lines
8.7 KiB
Verilog
301 lines
8.7 KiB
Verilog
/*Copyright 2020-2021 T-Head Semiconductor Co., Ltd.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
module ahb_fifo(
|
|
biu_pad_haddr,
|
|
biu_pad_hburst,
|
|
biu_pad_hprot,
|
|
biu_pad_hsize,
|
|
biu_pad_htrans,
|
|
biu_pad_hwrite,
|
|
counter_num0,
|
|
cpu_clk,
|
|
cpu_rst_b,
|
|
fifo_biu_hready,
|
|
fifo_pad_haddr,
|
|
fifo_pad_hburst,
|
|
fifo_pad_hprot,
|
|
fifo_pad_hsize,
|
|
fifo_pad_htrans,
|
|
fifo_pad_hwrite,
|
|
pad_biu_hready
|
|
);
|
|
|
|
// &Ports; @20
|
|
input [31:0] biu_pad_haddr;
|
|
input [1 :0] biu_pad_hburst;
|
|
input [3 :0] biu_pad_hprot;
|
|
input [2 :0] biu_pad_hsize;
|
|
input [1 :0] biu_pad_htrans;
|
|
input biu_pad_hwrite;
|
|
input [31:0] counter_num0;
|
|
input cpu_clk;
|
|
input cpu_rst_b;
|
|
input pad_biu_hready;
|
|
output fifo_biu_hready;
|
|
output [31:0] fifo_pad_haddr;
|
|
output [1 :0] fifo_pad_hburst;
|
|
output [3 :0] fifo_pad_hprot;
|
|
output [2 :0] fifo_pad_hsize;
|
|
output [1 :0] fifo_pad_htrans;
|
|
output fifo_pad_hwrite;
|
|
|
|
// &Regs; @21
|
|
reg [1 :0] burst_counter;
|
|
reg burst_counter_dec;
|
|
reg burst_counter_start;
|
|
reg cur_state;
|
|
reg entry_vld;
|
|
reg hready_mask;
|
|
reg next_state;
|
|
reg [44:0] output_data;
|
|
|
|
// &Wires; @22
|
|
wire [31:0] biu_pad_haddr;
|
|
wire [1 :0] biu_pad_hburst;
|
|
wire biu_pad_hlock;
|
|
wire [3 :0] biu_pad_hprot;
|
|
wire [2 :0] biu_pad_hsize;
|
|
wire [1 :0] biu_pad_htrans;
|
|
wire biu_pad_hwrite;
|
|
wire burst_ctrl;
|
|
wire burst_trans;
|
|
wire count_done;
|
|
wire counter_done;
|
|
wire counter_en;
|
|
wire [31:0] counter_num0;
|
|
wire cpu_clk;
|
|
wire cpu_rst_b;
|
|
wire create_en;
|
|
wire create_en0;
|
|
wire fifo_biu_hready;
|
|
wire fifo_bypass;
|
|
wire [31:0] fifo_pad_haddr;
|
|
wire [1 :0] fifo_pad_hburst;
|
|
wire fifo_pad_hlock;
|
|
wire [3 :0] fifo_pad_hprot;
|
|
wire [2 :0] fifo_pad_hsize;
|
|
wire [1 :0] fifo_pad_htrans;
|
|
wire fifo_pad_hwrite;
|
|
wire [54:0] input_data;
|
|
wire [54:0] output_data0;
|
|
wire pad_biu_hready;
|
|
wire pop_en;
|
|
wire pop_req;
|
|
wire raddr_hit;
|
|
|
|
|
|
//set delay area
|
|
|
|
parameter IMEM_START = 32'h00000000;
|
|
parameter IMEM_END = 32'h0001ffff;
|
|
parameter DMEM_START = 32'h20000000;
|
|
parameter DMEM_END = 32'h2001ffff;
|
|
parameter SMEM_START = 32'h60000000;
|
|
parameter SMEM_END = 32'h6001ffff;
|
|
|
|
assign raddr_hit = ((biu_pad_haddr[31:0] >= SMEM_START) && (biu_pad_haddr[31:0] <= SMEM_END)
|
|
) && biu_pad_hprot[3];
|
|
// &Force("nonport", "raddr_hit"); @43
|
|
//****************************************************
|
|
// creat_ptr maintenance
|
|
//****************************************************
|
|
// when entry is invalid delay entry can be bypassed if any of following conditions is met:
|
|
// 1. write trans 2. sequential burst trans 3. addr miss delay area
|
|
assign fifo_bypass = (biu_pad_hwrite || burst_trans || !raddr_hit) && !entry_vld || ( counter_num0[31:0] == 32'h0) ;
|
|
assign create_en = biu_pad_htrans[1] && !entry_vld && !fifo_bypass;
|
|
|
|
//monitor burst trans
|
|
assign burst_ctrl = create_en && biu_pad_hburst[1];
|
|
assign burst_trans = (cur_state == 1'b1) ;
|
|
//burst fsm
|
|
always @(posedge cpu_clk or negedge cpu_rst_b)
|
|
begin
|
|
if (!cpu_rst_b)
|
|
cur_state <= 1'b0;
|
|
else
|
|
cur_state <= next_state;
|
|
end
|
|
|
|
// &CombBeg; @64
|
|
always @( cur_state
|
|
or burst_ctrl
|
|
or fifo_biu_hready
|
|
or count_done
|
|
or biu_pad_htrans[1])
|
|
begin
|
|
burst_counter_start = 1'b0 ;
|
|
burst_counter_dec = 1'b0 ;
|
|
|
|
case(cur_state)
|
|
1'b0:
|
|
begin
|
|
if(burst_ctrl)
|
|
begin
|
|
next_state = 1'b1;
|
|
burst_counter_start = 1'b1;
|
|
end
|
|
else
|
|
next_state = 1'b0;
|
|
end
|
|
1'b1:
|
|
begin
|
|
if (count_done && fifo_biu_hready)
|
|
begin
|
|
next_state = 1'b0;
|
|
end
|
|
else if(biu_pad_htrans[1] && fifo_biu_hready )
|
|
begin
|
|
burst_counter_dec = 1'b1;
|
|
next_state = 1'b1;
|
|
end
|
|
else
|
|
next_state = 1'b1;
|
|
end
|
|
endcase
|
|
// &CombEnd; @94
|
|
end
|
|
|
|
//burst counter
|
|
always @(posedge cpu_clk or negedge cpu_rst_b)
|
|
begin
|
|
if (!cpu_rst_b)
|
|
burst_counter[1:0] <= 2'b0;
|
|
else if (burst_counter_start) // wrap initial value
|
|
burst_counter[1:0] <= 2'b10;
|
|
else if (burst_counter_dec)
|
|
burst_counter[1:0] <= burst_counter[1:0] - 1'b1;
|
|
else
|
|
burst_counter[1:0] <= burst_counter[1:0];
|
|
end
|
|
|
|
assign count_done = (burst_counter[1:0] == 2'b0);
|
|
//****************************************************
|
|
// entry_vld maintenance
|
|
//****************************************************
|
|
always @(posedge cpu_clk or negedge cpu_rst_b)
|
|
begin
|
|
if (!cpu_rst_b)
|
|
entry_vld <= 1'b0;
|
|
else if (create_en)
|
|
entry_vld <= 1'b1;
|
|
else if (pop_en)
|
|
entry_vld <= 1'b0;
|
|
end
|
|
|
|
//****************************************************
|
|
// entry delay counter maintenance
|
|
//****************************************************
|
|
|
|
|
|
assign counter_en = create_en;
|
|
// &Instance("ahb_fifo_counter", "x_counter_entry0"); @129
|
|
ahb_fifo_counter x_counter_entry0 (
|
|
.counter_done (counter_done),
|
|
.counter_en (counter_en ),
|
|
.counter_load (counter_num0),
|
|
.cpu_clk (cpu_clk ),
|
|
.cpu_rst_b (cpu_rst_b )
|
|
);
|
|
|
|
// &Connect (.counter_load (counter_num0 ), @130
|
|
// .counter_en (counter_en ), @131
|
|
// .counter_done (counter_done ) @132
|
|
// ); @133
|
|
|
|
//****************************************************
|
|
// pop logic maintenance
|
|
//****************************************************
|
|
|
|
assign pop_req = counter_done && entry_vld;
|
|
assign pop_en = pop_req && pad_biu_hready;
|
|
|
|
|
|
//****************************************************
|
|
// entry content
|
|
//****************************************************
|
|
assign biu_pad_hlock = 1'b0;
|
|
assign input_data[44:0] = { biu_pad_hwrite, biu_pad_haddr[31:0], biu_pad_hburst[1:0], biu_pad_hlock,
|
|
biu_pad_hprot[3:0], biu_pad_hsize[2:0], biu_pad_htrans[1:0]} ;
|
|
|
|
|
|
assign create_en0 = create_en ;
|
|
|
|
// &Instance("ahb_fifo_entry", "x_ahb_fifo_entry0"); @156
|
|
ahb_fifo_entry x_ahb_fifo_entry0 (
|
|
.create_en (create_en0 ),
|
|
.data_in (input_data ),
|
|
.data_out (output_data0),
|
|
.entry_clk (cpu_clk ),
|
|
.entry_rst_b (cpu_rst_b )
|
|
);
|
|
|
|
// &Connect (.entry_clk (cpu_clk ), @157
|
|
// .entry_rst_b (cpu_rst_b ), @158
|
|
// .data_in (input_data ), @159
|
|
// .create_en (create_en0 ), @160
|
|
// .data_out (output_data0 ) @161
|
|
// ); @162
|
|
|
|
|
|
// &CombBeg; @165
|
|
always @( pop_en
|
|
or output_data0[44:0])
|
|
begin
|
|
case (pop_en)
|
|
1'b0: output_data[44:0] = 45'b0;
|
|
1'b1: output_data[44:0] = output_data0[44:0];
|
|
default:output_data[44:0] = 45'b0;
|
|
endcase
|
|
// &CombEnd; @171
|
|
end
|
|
|
|
|
|
|
|
//****************************************************
|
|
// i/o interface
|
|
//****************************************************
|
|
//mask ready signal to acheive trans delay
|
|
always @(posedge cpu_clk or negedge cpu_rst_b)
|
|
begin
|
|
if (!cpu_rst_b)
|
|
hready_mask <= 1'b1;
|
|
else if (create_en)
|
|
hready_mask <= 1'b0;
|
|
else if (pop_en)
|
|
hready_mask <= 1'b1;
|
|
else
|
|
hready_mask <= hready_mask;
|
|
end
|
|
|
|
|
|
assign fifo_pad_htrans[1:0] = fifo_bypass ? biu_pad_htrans[1:0] : output_data[1:0];
|
|
assign fifo_pad_hsize[2:0] = fifo_bypass ? biu_pad_hsize[2:0] : output_data[4:2];
|
|
assign fifo_pad_hprot[3:0] = fifo_bypass ? biu_pad_hprot[3:0] : output_data[8:5];
|
|
assign fifo_pad_hlock = fifo_bypass ? biu_pad_hlock : output_data[9];
|
|
assign fifo_pad_hburst[1:0] = fifo_bypass ? biu_pad_hburst[1:0] : output_data[11:10];
|
|
assign fifo_pad_haddr[31:0] = fifo_bypass ? biu_pad_haddr[31:0] : output_data[43:12];
|
|
assign fifo_pad_hwrite = fifo_bypass ? biu_pad_hwrite : output_data[44];
|
|
|
|
|
|
// &Force("nonport", "fifo_pad_hlock"); @204
|
|
|
|
assign fifo_biu_hready = pad_biu_hready && hready_mask;
|
|
// &Force("output", "fifo_biu_hready"); @208
|
|
|
|
// &ModuleEnd; @210
|
|
endmodule
|
|
|
|
|