📄 lm_last.v
字号:
//------------------------------------------------------------------------------
//
// Name: Master Memory 32 Example
// Module Name: lm_last
// Company: Altera Corporation www.altera.com
//
// Functional Description:
//
// This module generates lm_last
//
// Copyright:
// Copyright 2004 Altera Corporation, All rights Reserved
//
//------------------------------------------------------------------------------
`timescale 1ns/1ns
module lm_last (/*AUTOARG*/
// Outputs
lm_lastn,
// Inputs
clk, rstn, wr_rdn, lm_req32n, lm_dxfrn, lm_tsr, xfr_length,
abnormal_term
);
parameter width = 10; // width of the xfr_length
input clk; // clock
input rstn; // Active low reset
input wr_rdn; // write = 1, read = 0
input lm_req32n; // 32-bit request
input lm_dxfrn; // local master data transfer
input [9:0] lm_tsr; // local master transaction status register
input [width:0] xfr_length; // # of transfers required
input abnormal_term; // Active high signal indicating
// an abnoraml termination occured. This signal should indicate
// that one of the following conditions occured
// Latency timeout
// Target Disconnect (with and with out data)
// Target Retry
// Target abort
// Master abort
output lm_lastn;
// Transfer counter
reg [width:0] local_xfr_count ;
wire reqn = lm_req32n;
// Decodes of xfr_length for 1 word, 2 words and 3 words
reg xfr_one_word; // transfer 1 word
reg xfr_two_words; // 2 words
always @ (posedge clk or negedge rstn)
if (!rstn) begin
xfr_one_word <= 1'b0;
xfr_two_words <= 1'b0;
end else if (abnormal_term) begin
xfr_one_word <= 1'b0;
xfr_two_words <= 1'b0;
end else if (!reqn) begin
xfr_one_word <= (xfr_length == 'h1) ? 1'b1 : 1'b0;
xfr_two_words <= (xfr_length == 'h2) ? 1'b1 : 1'b0;
end
wire cnt_enable = !lm_dxfrn ;
always @ (posedge clk or negedge rstn) begin
if (!rstn)
local_xfr_count <= 0;
else begin
if ( abnormal_term) // sync clear
local_xfr_count <= 0;
else if (!reqn) // sync load
local_xfr_count <= xfr_length;
else if (cnt_enable) // count enable
local_xfr_count <= local_xfr_count - 1'b1;
end
end // always @ (posedge clk or negedge rstn)
/**************************************************
lm last for writes is generated as shown below
*************************************************/
wire write_done = (wr_rdn & (local_xfr_count == 'h1));
/**************************************************
lm last for reads needs to consider 3 different cases
1) Signle transfer = !(xfr_one_word & !lm_dxfrn)
2) 2 WORD transfer = !(xfr_two_words & rising edge of lm_tsr[3])
3) Greater than 2 WORD Transfer = !((local_xfr_count == 'h3) &
!lm_dxfrn);
*************************************************/
// Generate rising edge of lm_tsr[3]
reg pci_data_phase_delayed; // delayed version of pci_data_phase lm_tsr[3]
always @ (posedge clk or negedge rstn) begin
if (!rstn)
pci_data_phase_delayed <= 1'b0;
else
pci_data_phase_delayed <= lm_tsr[3];
end
// detect rising edge of pci_data_phase
wire pci_data_phase_rising = lm_tsr[3] & !pci_data_phase_delayed;
// First 2 cases i.e. Single transfer and 2 WORD transfer
reg rd_done1 ; // temporary variable for read lm last generation
always @ (posedge clk or negedge rstn)
if (!rstn)
rd_done1 <= 1'b0;
else
rd_done1 <= (( xfr_one_word & lm_tsr[1] ) | // single transfer
// for both reads/writes
(!wr_rdn & xfr_two_words & pci_data_phase_rising)) ; // 2 word reads
// Transfer for greater than 2 words is generated using a
// pipelined version of !((local_xfr_count == 'h3) & !lm_dxfrn);
wire rd_done2 = !wr_rdn & (local_xfr_count == 'h3);
wire lm_lastn = ! (rd_done1 | (!lm_dxfrn & (write_done | rd_done2)));
endmodule // lm_last
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -