assign mcu_xxx_addr = (rd_after_wr_reg || reg_valid_write_trans) ?
haddr_reg[ADDR_WIDTH+:] : haddr[ADDR_WIDTH+:];
assign mcu_xx_rd_n = rd_after_wr ? 'b1 : rd_after_wr_reg ? 1'b0 : ~valid_read_trans;
assign mcu_xxx_wr_n = ~(hready && reg_valid_write_trans);
assign mcu_xxx_dat = hwdata;
assign rd_after_wr = hready && valid_read_trans && reg_valid_write_trans;
----------------------------------------------------------------------------
assign hsize_error = BYTE_MASK ? ((hsize = SZ_DWORD) ||hsize[]) :
(hsize != SZ_WORD);
assign valid_trans = hready && hsel && htrans[] && !hsize_error;
assign error_trans = hready && hsel && htrans[] && hsieze_error;
assign valid_read_trans = valid_trans && !hwrite;
assign valid_write_trans = valid_trans && hwrite; -------------------------------------------------------------------------------
always@(posedge hclk or negedge hresetn)
begin
if(~hresetn)
begin
haddr_reg <=;
htrans_reg <= ;
hwrite_reg <= ;
hsize_reg <= ;
reg_valid_read_trans <=;
reg_valid_write_trans <= ;
end
else
begin
if(hready)
begin
haddr_reg <= haddr;
htrans_reg <= htrans;
hwrite_reg <= hwrite;
hsize_reg <= hsize;
reg_valid_read_trans <=valid_read_trans;
reg_valid_write_trans <= valid_write_trans;
end
end
end --------------------------------------------------------------------------------
always@(*)
begin
if(hready && reg_valid_write_trans)
begin
mcu_xxx_wr_en = 'b0;
case(hsize_reg)
SZ_BYTE:
case(haddr_reg[:])
'b00: mcu_xxx_wr_en[0] = 1'b1;
''b01: mcu_xxx_wr_en[] = 'b1;
'b10: mcu_xxxx_wr_en[2] = 1'b1;
'b11: mcu_xxx_wr_en [3] = 1'b1;
endcase SZ_HALF:
case(haddr_reg[])
'b0 : mcu_xxx_wr_en[1:0] = 2'b11;
'b1 : mcu_xxx_wr_en [3:2] = 2'b11;
endcase SZ_WORD:
mcu_xxx_wr_en = 'b1111; default:
mcu_xxx_wr_en = 'b1111; endcase
end
else
begin
mcu_xxx_wr_en = 'b0;
end
end
本code主要实现AHB时序转MEMORY接口时序:
由于,AHB总线读写都是2拍,在ready信号拉高时表示数据读写完成,并且下一拍地址传到总线上。
memory 读写时序,读时序也是2拍,所以可以直接使用AMB总线的读使能。但写时序不一样。对于memory读使能有效时,可以立即把写数据送到写总线上,不像AHB写时必须2拍。所以写时,需要把AHB的HWRITE相关信号寄存一拍。
特别是,当先写后读时,要注意时序转换。即code中rd_after_wr。目前理解的是,整体把读使能也寄存了一拍。