📄 single_transaction_slave.v
字号:
// Copyright (C) 1991-2001 Altera Corporation
// Any megafunction design, and related net list (encrypted or decrypted),
// support information, device programming or simulation file, and any other
// associated documentation or information provided by Altera or a partner
// under Altera's Megafunction Partnership Program may be used only to
// program PLD devices (but not masked PLD devices) from Altera. Any other
// use of such megafunction design, net list, support information, device
// programming or simulation file, or any other related documentation or
// information is prohibited for any other purpose, including, but not
// limited to modification, reverse engineering, de-compiling, or use with
// any other silicon devices, unless such use is explicitly licensed under
// a separate agreement with Altera or a megafunction partner. Title to
// the intellectual property, including patents, copyrights, trademarks,
// trade secrets, or maskworks, embodied in any such megafunction design,
// net list, support information, device programming or simulation file, or
// any other related documentation or information provided by Altera or a
// megafunction partner, remains with Altera, the megafunction partner, or
// their respective licensors. No other licenses, including any licenses
// needed under any third party's intellectual property, are provided herein.
`include "ahb_include.v"
//TOP MODULE
module single_transaction_slave (HSEL,
HCLOCK,
HADDRESS,
HWRITE,
HTRANS,
HSIZE,
HBURST,
HRESETn,
HWDATA,
HRDATA,
HRESP,
HREADY,
HREADY_in,
reg_write,
reg_address,
reg_wdata,
reg_rdata,
wait_sig,
clock_en);
// INPUTS
input HSEL; //Chip enable
input [31:0] HADDRESS; //AHB Address signals
input [31:0] HWDATA; //Data lines
input HWRITE; //High = Write Low = Read
input [1:0] HTRANS; //Transfer type. Only nonseq is supported
input [1:0] HSIZE; //Size of data packet. Only 32 is supported
input [2:0] HBURST; //Size of burst. Only 1 is supported
input HRESETn; //System reset. Active low
input HCLOCK; //system clock
input [31:0] reg_rdata; //Read data bus from register file
input wait_sig; //Signals wait condition from backend logic
input HREADY_in; //HREADY input
// OUTPUTS
output [1:0] HRESP; //Slave response to status of xfer
output [31:0] HRDATA; //Read Data bus
output HREADY; //Insert wait states
output [31:0] reg_wdata; //write data bus to the back end logic
output [31:0] reg_address; //register file address bus
output reg_write; //transfer direction control to register file
output clock_en; //Clock enable for register file
//Internal Declarations
reg [1:0] HRESP; //Statemachine output
reg HREADY; //HREADY output
reg hready_r; //HREADY register
reg [31:0] haddress_r; //haddress register
reg [1:0] htrans_r; //htrans register
reg [2:0] hburst_r; //hburst register
reg [2:0] hsize_r; //hsize register
reg hwrite_r; //hwrite register
reg latch_bus;
reg [1:0] slave_state;
//PARAMETERS
parameter ADDRESS_PHASE = 2'b00, //State machine states
DATA_PHASE = 2'b10,
ERROR_PHASE = 2'b01,
WAIT_PHASE = 2'b11;
//Main Code
assign reg_wdata = HWDATA;
assign HRDATA = reg_rdata;
assign reg_address = haddress_r;
assign reg_write = hwrite_r;
assign clock_en = latch_bus;
always @(posedge HCLOCK or negedge HRESETn )
begin
if(HRESETn == 1'b0)
begin // Async Reset
slave_state <= ADDRESS_PHASE;
HRESP <= `OKAY;
hready_r <= 1'b1;
latch_bus <= 1'b0;
haddress_r <= 32'd0;
htrans_r <= 2'd0;
hburst_r <= 3'd0;
hsize_r <= 3'd0;
hwrite_r <= 1'd0;
end
else
begin
case (slave_state)
ADDRESS_PHASE:
begin
if(HSEL == 1'b0 || wait_sig ==1'b0)
begin // Slave not selected
slave_state <= ADDRESS_PHASE;
hready_r <= 1'b1;
HRESP <= `OKAY;
latch_bus <= 1'b0;
end
else if(HTRANS == `IDLE)
begin
slave_state <= ADDRESS_PHASE;
hready_r <= 1'b1;
HRESP <= `OKAY;
latch_bus <=1'b0;
end
else if(HSIZE != `AHB_WORD)
begin // Only supports word transactions
slave_state <= ERROR_PHASE;
hready_r <= 1'b0;
HRESP <= `ERROR;
latch_bus <= 1'b0;
end
else if(HBURST > `INCR)
begin // Only supports unspecfied INCR and single transactions
slave_state <= ERROR_PHASE;
hready_r <= 1'b0;
HRESP <= `ERROR;
latch_bus <= 1'b0;
end
else if(HADDRESS[4:0] > 16)
begin // attached register file only has 16 location
slave_state <= ERROR_PHASE;
hready_r <= 1'b0;
HRESP <= `ERROR;
latch_bus <= 1'b0;
end
else if(HTRANS == `NONSEQ)
begin // Single transaction
haddress_r <= HADDRESS; // latch in address and control as it is not going to be valid on next clock
hwrite_r <= HWRITE;
hburst_r <= HBURST;
hsize_r <= HSIZE;
htrans_r <= HTRANS;
slave_state <= DATA_PHASE;
HRESP <= `OKAY;
latch_bus <= 1'b1;
if(HWRITE)
begin
hready_r <= 1'b1;
end
else
begin
hready_r <= 1'b0;
end
end // elseif
end // Address Phase
ERROR_PHASE:
begin
slave_state <= ADDRESS_PHASE;
hready_r <= 1'b1;
HRESP <= `ERROR;
latch_bus <= 1'b0;
end
WAIT_PHASE:
begin
haddress_r <= HADDRESS; // latch in address and control as it is not going to be valid on next clock
hwrite_r <= HWRITE;
hburst_r <= HBURST;
hsize_r <= HSIZE;
htrans_r <= HTRANS;
slave_state <= DATA_PHASE;
HRESP <= `OKAY;
hready_r <= 1'b1;
latch_bus <= 1'b1;
end
default:
begin // Data phase
if(HTRANS == `IDLE)
begin
slave_state <= ADDRESS_PHASE;
hready_r <= 1'b1;
HRESP <= `OKAY;
latch_bus <= 1'b0;
end
else if(HADDRESS[4:0] > 16)
begin // Highest address in reg file is 20
slave_state <= ERROR_PHASE;
hready_r <= 1'b0;
HRESP <= `ERROR;
latch_bus <= 1'b0;
end
else if(HTRANS == `BUSY)
begin
slave_state <= ERROR_PHASE;
hready_r <= 1'b0;
HRESP <= `ERROR;
latch_bus <= 1'b0;
end
else if(HTRANS != `NONSEQ)
begin
slave_state <= ADDRESS_PHASE;
hready_r <= 1'b1;
HRESP <= `OKAY;
latch_bus <= 1'b0;
end
else if(HTRANS == `NONSEQ)
begin
haddress_r <= HADDRESS; // latch in address and control as it is not going to be valid on next clock
hwrite_r <= HWRITE;
hburst_r <= HBURST;
hsize_r <= HSIZE;
htrans_r <= HTRANS;
slave_state <= WAIT_PHASE;
HRESP <= `OKAY;
hready_r <= 1'b0;
latch_bus <= 1'b1;
end
end // default
endcase
end // if
end //always
always@(wait_sig or hready_r)
begin
if(wait_sig == 0)
HREADY = 1'b0;
else
HREADY = hready_r;
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -