module ahb_slave(
input wire clk ,
input wire rst_n ,
input wire hsel ,
input wire hwrite ,
input wire [1:0] htrans ,
input wire [31:0] haddr ,
input wire [31:0] hwdata ,
input wire hready ,
output reg [31:0] hrdata ,
output wire hreadyout
);
parameter BASE_ADDR = 32'h0000_0000;
parameter TEST_REG0 = 32'h0000_0000;
parameter TEST_REG1 = 32'h0000_0004;
parameter TEST_REG2 = 32'h0000_0008;
reg [31:0] test_reg0;
reg [31:0] test_reg1;
reg [31:0] test_reg2;
reg [31:0] haddr_dly;
reg [1:0] cur_state;
reg [1:0] nxt_state;
wire req;
assign req = hsel && htrans[1];
localparam IDLE = 2'b00,
WRITE = 2'b01,
READ = 2'b10;
always @(posedge clk, negedge rst_n) begin
if(rst_n == 1'b0) begin
haddr_dly <= #1 32'h0;
end
else begin
haddr_dly <= #1 haddr;
end
end
always @(posedge clk, negedge rst_n) begin
if(rst_n == 1'b0) begin
cur_state <= #1 2'b00;
end
else begin
cur_state <= #1 nxt_state;
end
end
always @(*) begin
case(cur_state)
IDLE: begin
if(req && hwrite) begin
nxt_state = WRITE;
end
else if(req && !hwrite) begin
nxt_state = READ;
end
else begin
nxt_state = cur_state;
end
end
WRITE: begin
if(hready) begin
if(req) begin
if(hwrite)
nxt_state = WRITE;
else
nxt_state = READ;
end
else
nxt_state = IDLE;
end
else
nxt_state = cur_state;
end
READ: begin
if(hready) begin
if(req) begin
if(hwrite)
nxt_state = WRITE;
else
nxt_state = READ;
end
else
nxt_state = IDLE;
end
else
nxt_state = cur_state;
end
default: nxt_state = IDLE;
endcase
end
always @(posedge clk, negedge rst_n) begin
if(rst_n == 1'b0) begin
test_reg0 <= #1 32'h0;
end
else if(cur_state == WRITE && haddr_dly == (BASE_ADDR + TEST_REG0) && hready) begin
test_reg0 <= #1 hwdata;
end
end
always @(posedge clk, negedge rst_n) begin
if(rst_n == 1'b0) begin
test_reg1 <= #1 32'h0;
end
else if(cur_state == WRITE && haddr_dly == (BASE_ADDR + TEST_REG1) && hready) begin
test_reg1 <= #1 hwdata;
end
end
always @(posedge clk, negedge rst_n) begin
if(rst_n == 1'b0) begin
test_reg2 <= #1 32'h0;
end
else if(cur_state == WRITE && haddr_dly == (BASE_ADDR + TEST_REG2) && hready) begin
test_reg2 <= #1 hwdata;
end
end
//================read==============
always @(*) begin
hrdata = 32'h0;
if(cur_state == READ && hready) begin
case(haddr_dly)
BASE_ADDR + TEST_REG0: hrdata = test_reg0;
BASE_ADDR + TEST_REG1: hrdata = test_reg1;
BASE_ADDR + TEST_REG2: hrdata = test_reg2;
default: hrdata = 32'h0;
endcase
end
end
assign hready_out = 1'b1;
endmodule
一个简单的ahb slave
最新推荐文章于 2024-05-06 10:41:42 发布