?? maincontrol.v
字號:
`timescale 1ns / 1ps
////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 17:18:45 01/18/06
// Design Name:
// Module Name: maincontrol
// Project Name:
// Target Device:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////
//注意:100M猝發讀寫:的確切含義是以100M采樣,以更高的頻率(系統的工作時鐘,暫定為105MHz)讀寫SDRAM,以50M的速度從pci讀取數據
//在FPGA本地側的控制邏輯(從PCI—FIFO讀取數據的邏輯)一定要與PCI9054的50M時鐘一致
module maincontrol (clk,clk50m,doing_precharge,rd_count,doing_refresh,lwr,blast,ads,sd_data_out,sd_rst,addr,do_write,do_read,do_write_ack,do_read_ack,ainit,FIFO_ad_rd,FIFO_ad_wr,pci_data
,sddataout_reg1);
//-------------------------IO
input clk;
input clk50m;
input doing_precharge;
input doing_refresh;
input [31:0] sd_data_out;
input [1:0]rd_count;
input lwr;
input blast;
input ads;
input do_read_ack;
input do_write_ack;
output sd_rst;
output [12:0] addr;
output do_write;
output do_read;
output ainit;
output FIFO_ad_rd;
output FIFO_ad_wr;
output sddataout_reg1;
inout [31:0] pci_data;
//---------------------------REG
reg sd_rst;
reg [12:0] addr;
reg do_write;
reg do_read;
reg ainit;
reg FIFO_ad_wr;
reg [2:0] rst_counter;
reg [7:0] read_counter;
reg [7:0] write_counter;
reg [31:0] reg_data;
reg [31:0] pci_out_reg;
reg mem_write_ena;
reg [31:0] sddataout_reg1;
reg read_ack_reg1;
reg [3:0] next_state;
//---------------------------------------wire 用于連接FIFO core和邏輯
wire [1:0] rd_count;
wire FIFO_ad_rd;
wire [31:0] mem_data_out;
//---------------------------------------parameter
parameter reset=4'd0,
IDLE=4'd1,
arbitrate =4'd2,
send_write_cmd=4'd3,
write_wait=4'd4,
write_burst=4'd5,
precharge_wait=4'd6,
send_read_cmd=4'd7,
read_wait=4'd8,
burst_read=4'd9;
//-------------------------------------------------------------------FIFO_ad_rd
assign FIFO_ad_rd = do_write_ack;
//--------------------------------------------------------------------
always@(posedge clk)
begin
if(!sd_rst)
begin
read_ack_reg1<=1'b0;
end
else
begin
read_ack_reg1<=do_read_ack;
end
end
//-----------------------------------------------------------------state machine
//各個狀態的操作:
always @(posedge clk)
begin
case (next_state)
reset:
begin
sd_rst<=1'b0;
addr<=13'd0;
do_write<=1'b0;
do_read<=1'b0;
ainit<=1'b1;
write_counter<=9'd0;
FIFO_ad_wr<=1'b0;
mem_write_ena<=1'b0; //停止向pcimem寫數據
if(rst_counter==3'd7) ////將reset狀態延長7個周期
begin
rst_counter<=3'd0;
next_state<=IDLE;
end
else
begin
rst_counter<=rst_counter+1;
next_state<=reset;
end
end
//----------------------------------------------------------------------------------
IDLE:
begin
rst_counter<=3'd0;
sd_rst<=1'b1;
ainit<=1'b0;
do_read<=1'b0;
do_write<=1'b0;
write_counter<=9'd0;
FIFO_ad_wr<=1'b0;//停止向ad FIFO寫數據
if(lwr&(!blast)) //每當pci寫入數據或命令時,跳轉至“判斷”狀態
next_state<=arbitrate;
else next_state<=IDLE;
end
//------------------------------------------------------------------------------------------------
arbitrate:
begin
if(reg_data==32'd0) //reset命令 ,跳轉之reset狀態
begin
sd_rst<=1'b0;
next_state<=reset;
end
else if(reg_data==32'd2147479278) //發出讀行命令,跳轉至send_read_cmd狀態
next_state<=send_read_cmd;
else if(reg_data==32'd47) //發出寫命令,跳轉至send _write_cmd狀態
next_state<=send_write_cmd;
else next_state<=IDLE;
end
//-----------------------------------------------------------------------------------------
send_write_cmd:
begin
FIFO_ad_wr<=1'b1; //開始向FIFO寫數據
sd_rst<=1'b1;
if(doing_refresh) //如果正在進行refresh,等結束后再寫
begin
do_write<=1'b0; //停止向SDRAM寫數據
next_state<=send_write_cmd;
end
else
begin
if(rd_count>=2'b01)
begin
do_write<=1'b1;
next_state<=write_wait;
end
else
begin
do_write<=1'b0;
next_state<=send_write_cmd;
end
end
end
//---------------------------------------------------------------------------------------
write_wait: //等待寫入開始
begin
FIFO_ad_wr<=1'b1;//將AD數據寫入FIFO
sd_rst<=1'b1;
if(do_write_ack) //收到寫應答,表示下個周期數據開始有效的寫入SDRAM
begin
do_write <=1'b0;
next_state<=write_burst; //進入寫猝發
end
else
begin
do_write<=1'b1;
next_state<=write_wait;
end
end
//--------------------------------------------------------------------------------------
write_burst: //等待寫猝發結束
begin
FIFO_ad_wr<=1'b1;
sd_rst<=1'b1;
if(do_write_ack)
begin
next_state<=write_burst;
end
else //猝發寫入完成
begin
addr<=addr+1; //進行過precharge之后,行地址加1
next_state<=precharge_wait;
end
end
//----------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
precharge_wait: //等待precharge結束
begin
sd_rst<=1'b1;
if(doing_precharge) // 在sdram控制模塊中,每寫完一行并precharge后,
begin
FIFO_ad_wr<=1'b1;
next_state<=precharge_wait; //等待auto refresh完成
end
else
begin //precharge結束之后
if(addr==13'b1111111111111) //行地址和BANK地址加滿
begin
addr<=13'd0; //ba和行地址清零
// FIFO_ad_rd<=1'b0;//停止讀AD FIFO
FIFO_ad_wr<=1'b0;//停止向AD FIFO寫數據
next_state<=IDLE;
end
else
begin
FIFO_ad_wr<=1'b1;
next_state<=send_write_cmd;
end //沒有寫完2M的數據,再接著寫
//在send_write_cmd狀態中等待refresh結束
end
end
//---------------------------------------------------------------------------------
send_read_cmd: //發出讀命令
begin
sd_rst<=1'b1;
do_write<=1'b0; //添加,保證穩定
if(doing_refresh) //如果正在進行refresh,等結束后再讀
begin
do_read<=1'b0; //停止讀SDRAM
next_state<=send_read_cmd;
end
else
begin
do_read<=1'b1;
next_state<=read_wait;
end
end
//--------------------------------------------------------------------------------
//調試屏蔽
read_wait: // 等待讀應答信號
begin
sd_rst<=1'b1;
do_write<=1'b0; //添加,保證穩定
// if(do_read_ack) //當收到do_read_ack后表示下一個周期數據有效,開始接受數據
if(read_ack_reg1) //當收到read_ack_reg1后表示下一個周期數據有效,開始接受數據
begin
do_read<=1'b0;
//mem[0]<= sd_data_out;//
mem_write_ena<=1'b1; //開始向pcimem寫數據
next_state<=burst_read;
end
else next_state<=read_wait;
end
//----------------------------------------------------------------------------------
burst_read: //讀猝發,將SDRAM的數據以行猝發的方式讀到FPGA中
begin
sd_rst<=1'b1;
do_write<=1'b0;
// if(mem_addr==9'd256) //到256后清零,有效mem地址是0-255,共256個
if(write_counter==8'd255)
begin
write_counter<=8'd0;
mem_write_ena<=1'b0; //停止向pcimem寫數據
addr<=addr+1; //讀完一行后,行地址加1
next_state<=IDLE; //寫完了一行(256列),進入IDLE狀態
end
else
begin
mem_write_ena<=1'b1; //開始向pcimem寫數據
write_counter<=write_counter+1;
next_state<= burst_read;
end
end
//------------------------------------------------------------------------------
default:
next_state<=IDLE;
endcase
end
//--------------------------------------------------------------read pci_mem
always@(posedge clk50m or negedge sd_rst) //與pci側的50M時鐘同步
begin
if(!sd_rst)
begin
read_counter<=8'd0;
pci_out_reg<=32'd0;
end
else if((!lwr)&(!ads)) //當pci發出讀命令時
begin
if(read_counter==8'd255) //只有發出讀命令時才改變地址,否則地址不變
read_counter<=8'd0;
else
begin
read_counter<=read_counter+1;
pci_out_reg<=mem_data_out;
end
end
end
//-----------------------------------------------------------------------------雙向總線pci_data的控制
//pci端雙向總線的輸入,將輸入的命令存儲在reg_data
always@(posedge clk50m or negedge sd_rst) //與pci側的50M時鐘同步
begin
if(!sd_rst)
reg_data<=32'd0;
else if(lwr&(!blast)) //每當pci寫入命令時
reg_data<=pci_data; // 將輸入命令寄存
end
//-------------------------------------------------------------------------
//pci端雙向總線的輸出
assign pci_data = ((!lwr)&(!ads))? pci_out_reg: 32'hzzzzzzzz;//當輸出使能時,將pci_mem的數據輸出,否則為高阻
//-------------------------------------------------------------------
//using pcimem
pcimem mypcimem(
.addra(write_counter[7:0]),
.addrb(read_counter[7:0]),
.clka(clk),
.clkb(clk50m),
.dina(sd_data_out),
.doutb(mem_data_out),
.wea(mem_write_ena));
always@(posedge clk or negedge sd_rst) //將從sdram中讀回的數據用寄存器存儲,
begin
if(!sd_rst)
begin
sddataout_reg1<=32'd0;
end
else
begin
sddataout_reg1<=sd_data_out;
end
end
endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -