📄 read_master.v
字号:
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2007 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* *
******************************************************************************/
module read_master
(
//Global Avalon interface siganals
gls_clk,
gls_reset_n,
//Signals for Avalon-MM master port
avm_m1_address,
//address, // debug - full address output
avm_m1_byteenable, // for future byte lane control
avm_m1_read_n,
avm_m1_readdata,
avm_m1_waitrequest,
// Signals from slave registers
addr_reg,
len_reg,
go,
avm_m1_byteenable_mask, // debug - for byteenable mask values
read_busy,
data_in_ready,
count, // debug - check count value and for future enhancement
data_to_process
);
input gls_clk;
input gls_reset_n;
output [31:0]avm_m1_address;
//output [31:0]address; // debug - full address output
output [3:0]avm_m1_byteenable; //for future byte lane control
output avm_m1_read_n;
input [31:0] avm_m1_readdata;
input avm_m1_waitrequest;
input [31:0]addr_reg;
input [15:0]len_reg;
input go;
output [3:0]avm_m1_byteenable_mask; // debug - for byteenable mask values
output read_busy;
output data_in_ready;
output [15:0]count; // debug - check count value and for future enhancement
output [31:0]data_to_process;
wire [31:0] avm_m1_address = { addr[31:2], 2'b0 }; // Lower address bits are not used assume world aligned addresses
//wire [31:0] address = addr;
// Check for valid read data on the master port by looking for waitrequest with each read
wire data_in_ready = ( (avm_m1_read_n == 1'b0) && !avm_m1_waitrequest) ? 1'b1 : 1'b0;
// passing readdata to task logic
// mask data to process based on byteenable mask
assign data_to_process[31:0] = (avm_m1_byteenable_mask == 4'b0001) ? ( 32'h000000FF & avm_m1_readdata[31:0]) :
(avm_m1_byteenable_mask == 4'b0011) ? ( 32'h0000FFFF & avm_m1_readdata[31:0]) :
(avm_m1_byteenable_mask == 4'b0111) ? ( 32'h00FFFFFF & avm_m1_readdata[31:0]) :
avm_m1_readdata[31:0];
reg [31:0] addr;
reg avm_m1_read_n;
reg [15:0] count_tmp;
wire [3:0] avm_m1_byteenable = 4'b1111; // drive byteenables high
reg [3:0] avm_m1_byteenable_mask;
reg read_busy;
//Statemachine block for controlling read master signals
always @(posedge gls_clk or negedge gls_reset_n)
begin
if (gls_reset_n == 1'b0)
begin
count_tmp <= 'b0;
read_busy <= 1'b0;
addr <= 'b0;
avm_m1_byteenable_mask <= 4'b0000;
avm_m1_read_n <= 1'b1;
read_busy <= 1'b0;
end
else if (go) // loads count and start read master statemachine
begin
count_tmp <= len_reg - 3'h4; // decrement count for this initial load/read state
addr <= addr_reg ; // loads address - must be 32-bit word aligned addess
avm_m1_byteenable_mask <= 4'b1111;
avm_m1_read_n <= 1'b1;
read_busy <= 1'b1;
end
else if (count > 3 && data_in_ready) // Main loop for read master statemachine
begin
count_tmp <= count_tmp - 3'h4;
addr <= addr + 3'h4;
avm_m1_byteenable_mask <= 4'b1111; // assert byteenable mask byte lane(s) 3,2,1,0
avm_m1_read_n <= 1'b0;
read_busy <= 1'b1;
end
else if (count == 3 && data_in_ready) // Last read for un-aligned word lengths - 3 bytes
begin
count_tmp <= count_tmp - 3'h3;
addr <= addr + 3'h4;
avm_m1_byteenable_mask <= 4'b0111; // assert byteenable mask byte lane(s) 2,1,0
avm_m1_read_n <= 1'b0;
read_busy <= 1'b1;
end
else if (count == 2 && data_in_ready) // Last read for un-aligned word lengths - 2 bytes
begin
count_tmp <= count_tmp - 3'h2;
addr <= addr + 3'h4;
avm_m1_byteenable_mask <= 4'b0011; // assert byteenable mask byte lane(s) 1,0
avm_m1_read_n <= 1'b0;
read_busy <= 1'b1;
end
else if (count == 1 && data_in_ready) // Last read for un-aligned word lengths - 1 bytes
begin
count_tmp <= count_tmp - 3'h1;
addr <= addr + 3'h4;
avm_m1_byteenable_mask <= 4'b0001; // assert byteenable mask byte lane(s) 0
avm_m1_read_n <= 1'b0;
read_busy <= 1'b1;
end
else if (count ==0 && !data_in_ready) // Hold outputs if waitrequest asserted during last read cycle
begin
count_tmp <= count_tmp;
addr <= addr ;
avm_m1_byteenable_mask <= avm_m1_byteenable_mask;
avm_m1_read_n <= avm_m1_read_n;
read_busy <= read_busy;
end
else if (count ==0) // byte count is zero and the exit condition for read master statemachine
begin
addr <= 'b0; // clear address
avm_m1_byteenable_mask <= 4'b0000; // clear byteenables
avm_m1_read_n <= 1'b1; // stop reading
read_busy <= 1'b0; // deassert busy bit
end
else // Starts the read cycle after a load or holds master outputs static when waitrequest asserted
begin
count_tmp <= count_tmp;
addr <= addr ;
avm_m1_byteenable_mask <= avm_m1_byteenable_mask;
avm_m1_read_n <= 1'b0; // starts the read cycle
read_busy <= 1'b1;
end
end
assign count = count_tmp;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -