📄 mstr_mem32.v
字号:
//------------------------------------------------------------------------------
//
// Name: Master Memory 32 Example
// Module Name: mstr_mem32
// Company: Altera Corporation www.altera.com
//
// Functional Description:
//
// This module is the top level of the local design for the Master
// 32-bit memory example. The design example shows how to interface
// a 32-bit Master Function to a synchronous memory like altsyncram.
//
// This module also shows the sample master control logic required
// to handle the case when the transaction is terminated by either a Target
// Retry, Target Disconnect or Master Latency Timeout. If the
// transaction is terminated before the entire data is transmitted,
// the control logic will start a new PCI transaction and will
// transfer the remaining data.
//
// The length, direction and the address of the transfer are
// controlled by input signals.
//
// This module instantiates the module lm_last which generates the
// signal lm_lastn. It also instantiates a 256x32 synchronous memory
// (altsyncram).
//
// Copyright:
// Copyright 2004 Altera Corporation, All rights Reserved
//
//------------------------------------------------------------------------------
`timescale 1ns/1ns
module mstr_mem32 (/*AUTOARG*/
// Outputs
l_adi, l_cbeni, lm_req32n, lm_lastn, lm_rdyn, lt_rdyn, lt_abortn,
lt_discn, lirqn, done, error,
// Inputs
clk, rstn, l_adro, l_dato, l_beno, l_cmdo, lm_adr_ackn, lm_ackn,
lm_dxfrn, lm_tsr, lt_framen, lt_ackn, lt_dxfrn, lt_tsr, cmd_reg,
stat_reg, cache, START_I, PCI_ADDR_I, LOCAL_ADDR_I, LOCAL_DATA_I,
PCI_CMD_I, XFR_LENGTH_I
);
input clk;
input rstn;
//Data Path Signals
output [31:0] l_adi;
output [3:0] l_cbeni;
input [31:0] l_adro;
input [31:0] l_dato;
input [3:0] l_beno;
input [3:0] l_cmdo;
// Master O/p Control signals
output lm_req32n;
output lm_lastn;
output lm_rdyn;
// Master i/p control signals
input lm_adr_ackn;
input lm_ackn;
input lm_dxfrn;
input [9:0] lm_tsr;
// Target o/p control signals
output lt_rdyn;
output lt_abortn;
output lt_discn;
output lirqn;
input lt_framen;
input lt_ackn;
input lt_dxfrn;
input [11:0] lt_tsr;
// Misc signals
input [6:0] cmd_reg;
input [6:0] stat_reg;
input [7:0] cache;
// TB Master control signals
input START_I;
input [31:0] PCI_ADDR_I;
input [31:0] LOCAL_ADDR_I;
input [31:0] LOCAL_DATA_I;
input [3:0] PCI_CMD_I;
input [10:0] XFR_LENGTH_I;
output done; // transaction completed
output error; // transaction error
reg done, error;
// The target interface is not used in this example
// Target Control Signals
wire lt_abortn = 1'b1;
wire lt_rdyn = 1'b1;
wire lt_discn = 1'b1;
wire lirqn = 1'b1;
// Register the TB control signals
reg START;
reg [31:0] PCI_ADDR, LOCAL_ADDR, LOCAL_DATA;
reg [3:0] PCI_CMD;
reg [10:0] XFR_LENGTH;
always @ (posedge clk)
begin
START <= START_I;
PCI_ADDR <= PCI_ADDR_I;
LOCAL_ADDR <= LOCAL_ADDR_I;
LOCAL_DATA <= LOCAL_DATA_I;
PCI_CMD <= PCI_CMD_I;
XFR_LENGTH <= XFR_LENGTH_I;
end
// Some renames of lm_tsr signals
wire pci_adr_phase = lm_tsr[2];
wire pci_data_xfr = lm_tsr[8];
wire pci_data_phase = lm_tsr[3];
// Master Control State Machine
// Declare the various inputs required
reg pci_data_phase_q;
always @ (posedge clk)
pci_data_phase_q <= pci_data_phase;
wire cycle_end = pci_data_phase_q & !pci_data_phase;
reg fatal_error; // Indicates mastor abort or target abort
reg do_retry; // Indicates one of the following
// 1) Target Retry
// 2) Target Disconnect with or without data
// 3) Master Latency timer expired
always @ (posedge clk or negedge rstn)
if (!rstn) begin
fatal_error <= 1'b0;
do_retry <= 1'b0;
end
else if (cycle_end) begin
fatal_error <= stat_reg[3] | stat_reg[4];
do_retry <= |lm_tsr[7:4];
end
reg xfr_done; // Indicates all the data has been transferred
// State Definitions
parameter [5:0] IDLE = 6'b00_0000,
REQ = 6'b00_0001,
ADR_PHASE = 6'b00_0010,
DATA_PHASE = 6'b00_0100,
DP_DONE = 6'b00_1000,
CHK_STATE = 6'b01_0000,
RETRY = 6'b10_0000;
//state machine
reg [5:0] m_state;
always @ (posedge clk or negedge rstn)
if (!rstn)
m_state <= IDLE;
else
case (m_state)
IDLE: begin
if (START)
m_state <= REQ;
else
m_state <= IDLE;
end
REQ: m_state <= ADR_PHASE;
ADR_PHASE: begin
if (lm_tsr[2])
m_state <= DATA_PHASE;
else
m_state <= ADR_PHASE;
end
DATA_PHASE: begin
if (cycle_end)
m_state <= CHK_STATE;
else if (!lm_lastn)
m_state <= DP_DONE;
else
m_state <= DATA_PHASE;
end
DP_DONE: begin
if (cycle_end)
m_state <= CHK_STATE;
else
m_state <= DP_DONE;
end
CHK_STATE: begin
if (fatal_error | xfr_done)
m_state <= IDLE;
else if (do_retry)
m_state <= RETRY;
end
RETRY: m_state <= REQ;
default: m_state <= IDLE;
endcase // case(cs[4:0])
// outputs from state machine
wire lm_req32n = (m_state == REQ) ? 1'b0: 1'b1;
wire data_sel = (m_state == DATA_PHASE | m_state == ADR_PHASE & lm_tsr[2]) ? 1'b1: 1'b0;
// command and wr_rdn load at the beginning of request
// wr_rdn = 1 PCI write local side read
// wr_rdn = 0 PCI read local side write
reg wr_rdn;
reg [3:0] command;
always @ (posedge clk or negedge rstn)
if(!rstn) begin
wr_rdn <= 1'b0;
command <= 4'h0;
end else if (m_state == IDLE & START) begin
command <= PCI_CMD;
wr_rdn <= PCI_CMD[0];
end
// lm_rdyn
reg lm_rdyn;
always @ (posedge clk or negedge rstn)
if (!rstn)
lm_rdyn <= 1'b1;
else
lm_rdyn <= !(( wr_rdn & (m_state == ADR_PHASE | m_state == DATA_PHASE))|
(!wr_rdn & (m_state == DATA_PHASE | m_state == DP_DONE)));
// counters to keep track of the PCI address and the Transfer count
reg [31:0] paddr; // PCI address
reg [10:0] xfr_cnt; // xfr counter
always @ (posedge clk or negedge rstn)
if (!rstn) begin
paddr <= 32'b0;
xfr_cnt <= 11'b0;
xfr_done <= 1'b0;
end else if (m_state == IDLE & START) begin
paddr <= PCI_ADDR;
xfr_cnt <= XFR_LENGTH;
xfr_done <= 1'b0;
end else if (pci_data_xfr) begin
paddr <= paddr + 4;
xfr_cnt <= xfr_cnt - 1;
xfr_done <= (xfr_cnt == 'h1);
end
// lm_last generation
wire abnormal_term = (fatal_error | do_retry ) & (m_state == CHK_STATE);
lm_last lm_last (.lm_lastn(lm_lastn),
.clk(clk),
.rstn(rstn),
.wr_rdn(wr_rdn),
.lm_req32n(lm_req32n),
.lm_dxfrn(lm_dxfrn),
.lm_tsr(lm_tsr),
.xfr_length(xfr_cnt),
.abnormal_term(abnormal_term)
);
/***********************************************************
* Local Address Counter logic
***********************************************************/
wire mem_rd_incr = !wr_rdn & !lm_dxfrn;
wire mem_wr_incr = wr_rdn & (!lm_ackn | !lm_req32n ) ;
wire mem_incr = (mem_wr_incr | mem_rd_incr) ;
// The following logic implements an up-down counter and keeps
// track of the number of DWORDs tranferred on the local side but
// not on the PCI bus during a PCI write transcation. The local
// address counter is decremented by the value in this counter when
// the state machine is in the RETRY state.
reg [1:0] pipe;
always @ (posedge clk or negedge rstn)
if (!rstn)
pipe <= 2'b0;
else begin
if (m_state == REQ & wr_rdn)
pipe <= 2'b1;
else if (wr_rdn)
case ({pci_data_xfr, mem_wr_incr})
2'b00: pipe <= pipe;
2'b01: pipe <= pipe + 1;
2'b10: pipe <= pipe - 1;
2'b11: pipe <= pipe;
endcase // case({pci_data_xfr, mem_wr_incr})
end // else: !if(!rstn)
wire undo = (m_state == RETRY) ? 1'b1: 1'b0;
reg [7:0] mem_addr;
always @ (posedge clk or negedge rstn)
if (!rstn)
mem_addr <= 8'b0;
else begin
if (m_state == IDLE)
mem_addr <= LOCAL_ADDR;
else if (m_state == RETRY & wr_rdn)
mem_addr <= (mem_addr ) - pipe;
else if (mem_incr)
mem_addr <= mem_addr + 1;
end
wire mem_wr_enable = !wr_rdn & !lm_dxfrn;
wire mem_rd_enable = wr_rdn & (!lm_req32n | !lm_ackn );
wire [31:0] mem_rd_data;
mem256x32 mem (.address(mem_addr),
.clock(clk),
.clken((mem_wr_enable | mem_rd_enable)),
.data (l_dato),
.wren(mem_wr_enable),
.q(mem_rd_data)
);
// Drive TB data in case of a configuration write
wire [31:0] t_rd_data = (command == 4'b1011) ? LOCAL_DATA : mem_rd_data;
// Drive PCI address and command on the address cyclce
wire [31:0] l_adi = data_sel ? t_rd_data : paddr;
wire [3:0] l_cbeni = data_sel ? 4'h0 : command;
// tb control signals
always @ (posedge clk or negedge rstn)
if (!rstn) begin
done <= 1'b0;
error <= 1'b0;
end else begin
if (m_state == IDLE & START ) begin
done <= 1'b0;
error <= 1'b0;
end else if (m_state == CHK_STATE) begin
done <= xfr_done;
error <= fatal_error;
end
end // else: !if(!rstn)
endmodule // mstr_mem32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -