abstractaccelerator/opene906/smart_run/logical/ahb/ahb_fifo.v

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