一个简单的ahb slave

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
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值