文章目录
👉关于AHB2APB的设计请看:AHB2APB设计
👉关于AHB2APB的验证请看:AHB2APB验证
该简单的同步桥的功能包括:
- 不支持PPROT、PSTRB;
- 不支持PSLVERR反馈ERROR信号,pslverr一直置为低;
- 不支持输出数据寄存;
- 支持输入数据寄存;
注:下面先进行代码的拆解,完整代码附于文末。
部分代码解释
1. 数据寄存控制信号
数据是否需要寄存一拍的控制信号的产生,如下代码:
//------数据寄存-------
wire rdata_reg_param; // REGISTER_RDATA,寄存读数据
wire wdata_reg_param; // REGISTER_WDATA ,寄存写数据
assign rdata_reg_param = (REGISTER_RDATA)? 1'b1 : 1'b0;
assign wdata_reg_param = (REGISTER_WDATA)? 1'b1 : 1'b0
2. 数据采样寄存的控制信号
输入数据什么时候采样到寄存器中停留一拍,这需要添加一个控制信号,产生如下:
// 采样输入数据到寄存器的控制信号
reg sample_wdata_flag;
wire sample_wdata_start = apb_select & HWRITE ;
wire sample_wdata_continue = sample_wdata_flag & PCLKEN;
always @(posedge HCLK or negedge HRESETn) begin
if (~HRESETn)
sample_wdata_flag <= 1'b0;
else if (sample_wdata_start | sample_wdata_continue)
sample_wdata_flag <= sample_wdata_start;
end
解释上面代码:
- 只有在 apb_select & HWRITE成立时,才会使sample_wdata_flag为高,进行HWDATA的采样寄存。
- 如果PCLKEN有效沿到来,并且此时sample_wdata_flag为高,那么 sample_wdata_flag仍然继续保持为高;
3. APB的选通信号
产生APB的选通信号apb_select,如下代码:
- 当AHB master开启传输时,APB才选通;
- HTRANS[1]代表SEQ或NONSEQ状态,即有传输进行的状态;
//------产生APB的sel信号-------
wire apb_sel;//状态机内部的信号
assign apb_sel = HSEL & HREADY & HTRANS[1];
4. ahb slave的地址处理
为了保证AHB 在地址映射时不出错,要对 ahb slave的地址(PADDR)做处理,确保1KB对齐。
//------产生APB的PADDR信号-------
reg [ADDRWIDTH-3:0] addr_reg;//HADDR
assign PADDR = {addr_reg, 2'b00};
//-----锁存控制信号------
always@(posedge HCLK or negedge HRESETn) begin
if(! HRESETn) begin
addr_reg <= 0;
write_reg <=0;
end
else if(apb_select) begin
addr_reg <= HADDR[ADDRWIDTH-1:2];//为了保证地址1KB对齐
write_reg <= HWRITE;
end
end
5. 状态机的描述
状态机的描述,采用三段式描述如下:
/*********************************
*--------==== 状态机 ====------
*********************************/
reg state,next_state;
//状态编码
parameter IDLE = 2'b00;//空闲状态
parameter WAIT = 2'b01;//等待输入数据寄存一拍
parameter SETUP = 2'b10;//传输建立状态,开始传输
parameter ENABLE = 2'b11;//传输完成状态,判断是否有下一次传输继续
always @(state or PREADY or PSLVERR or apb_select or rdata_reg_param or
PCLKEN or wdata_reg_param or HWRITE)
begin
case (state)
IDLE : begin
if (PCLKEN & apb_select & HWRITE)
next_state = WAIT; // 如果是写操作,就寄存一拍
else if (apb_select)
next_state = SETUP; // 如果是读操作,就不寄存
else
next_state = IDLE; // 其他情况则保持IDLE
end
WAIT : begin
if (PCLKEN)
next_state = SETUP; // 寄存一拍后到达SETUP状态,准备开始传输
else
next_state = WAIT; // PCLKEN 没到之前,保持WAIT
end
SETUP : begin
if (PCLKEN)
next_state = ENABLE; //
else
next_state = SETUP; //
end
ENABLE : begin
if (PREADY & PCLKEN & apb_sel)
next_state = SETUP; //如果紧接着还有传输
else if(!apb_sel)
next_state = IDLE;
else //如果此时PREDY为低
next_state = ENABLE; //PCLKEN没到之前,保持ENABLE状态
end
endcase
end
always @(posedge HCLK or negedge HRESETn) begin
if (~HRESETn)
state <= 2'b00;
else
state <= next_state;
end
always @(posedge HCLK or negedge HRESETn) begin
if (~HRESETn)
wdata_reg <= {32{1'b0}};
else if (PCLKEN & sample_wdata_flag)
wdata_reg <= HWDATA;
else
wdata_reg <= wdata_reg;
end
6. HREADYOUT信号的产生
HREADYOUT信号的产生,如下:
//-------HREADYOUT信号的产生-------
always @(state or PREADY or PCLKEN) begin
case (state)
IDLE : HREADYOUT = 1'b1;
WAIT : HREADYOUT = 1'b0;
SETUP : HREADYOUT = 1'b0;
ENABLE : HREADYOUT = PREADY & PCLKEN;
endcase
end
7. 返回给AHB的信号
返回给AHB的信号,如下:
//------返回给AHB的信号-------
assign HRDATA = PRDATA;
assign HRESP = 1'b0;
8. APB信号的生成
传递给APB的信号,如下:
//------产生APB的信号-------
wire apb_sel;//状态机内部的信号
reg [ADDRWIDTH-3:0] addr_reg;//HADDR
reg write_reg;//HWRITE
assign apb_sel = HSEL & HREADY & HTRANS[1];
assign PADDR = {addr_reg, 2'b00};
assign PWRITE = write_reg;
assign PWDATA = wdata_reg;
assign PSEL = (state == SETUP) | (state == ENABLE);
assign PENABLE = (state == ENABLE);
assign PSLVERR = 1'b0;
assign APBACTIVE = (HSEL & HTRANS[1]) | (state != 2'b00);