我用actel的030芯片实现显卡功能,fpga外扩一片ram作为显存,首先我需要实现CPU读写显存,我的代码如下:
module cpuRamPort( clk,rst,pRs,pRd,pWr,pCs,pBus,rAddr,rBus,rCs,rRd,rWr,rgbAddr,rgb );
input clk;
input rst;
input pRs,pRd,pWr,pCs; //pRs为指令、数据选择,其他为CPU的读写fpga的控制信号
inout [7:0] pBus; //CPU与FPGA之间的总线
output [16:0] rAddr; //外扩RAM的地址总线
inout [7:0] rBus; //外扩RAM的数据总线
output reg rCs,rRd,rWr; //外扩RAM的片选、读、写控制
input [16:0] rgbAddr; //液晶显示地址
output reg [7:0] rgb; //从ram中读取提供给液晶的RGB信号
reg [3:0] insReg; //fpga内的指令寄存器
reg [1:0] stat; //RAM接口状态机
reg [7:0] ramData; //从RAM的portAddr单元读取的数据
reg [7:0] portData; //CPU待写入ram的数据
reg portNew; //CPU写数据标志
reg ramAck; //ram保存CPU数据应答
reg [16:0] portAddr; //CPU读写ram的地址
//cpu与fpga的接口,实现cpu把数据写入portData,并指定ram地址portAddr
assign pBus = ( pRs==1 && pCs==0 && pRd==0 )? ramData:'8'hzz; //当cpu读取显存时,输出ramData
always @ ( posedge pWr or posedge ramAck ) //当pWr或ramAck时触发
begin
if( pWr )
begin
if( pCs==0 )
begin
if( pRs==0 )
insReg = pBus[3:0]; //当pRs为0时CPU把数据写入insReg寄存器
else
begin
case(insReg)
4'h0:portAddr[7:0] = pBus; //如果insReg==0则写入portAddr的低8位
4'h1:portAddr[15:8] = pBus; //如果insReg==1则写入portAddr的高8位
4'h2:begin
portData = pBus; //如果insReg==2则写入portData,并且置portNew标志
portNew = 1;
end
4'h5:portAddr[16] = pBus[0]; //如果insReg==5则写入portAddr的最高位
endcase
end
end
end
else
begin
portNew = 0; //如果ramAck有效则清除portNew标志
portAddr = portAddr+1; //并且portAddr加1
end
end
//把CPU写入的数据写入ram,或把ram中的数据读出到ramData或rgb
assign rAddr = (stat<2)? rgbAddr:portAddr; //分时地址切换前2个节拍为rgbAddr
assign rBus = (rCs==0 && rWr==0)? portData:8'hzz; //在写时序把来自cpu的数据portData输出到rBus总线
always @ ( negedge rst or posedge clk )
begin
if( !rst )
begin
stat = 0;
rCs = 1;
rRc = 1;
rWr = 1;
ramAck = 0;
end
else
begin
case(stat)
2'b00:
begin
rgb = rBus; //在接拍0把rgbAddr地址中的数据读出到rgb寄存器
rRd = 1;
rCs = 1;
rWr = 1;
stat = stat+1;
end
2'b01:
begin
rCs = 0;
if( portNew )
begin
rWr = 0; //如果有来自CPU的数据则写RAM
ramAck = 1; //并且置ramAck
end
else
begin
rRd = 0; //如果没有cpu写数据则把portAddr单元的内容读出到ramData
ramAck = 0;
end
stat = stat+1;
end
2'b10:
begin
if( !ramAck )ramData = rBus; //如果没有cpu写数据则把portAddr单元的内容读出到ramData
portAck = 0;
rCs = 1;
rWr = 1;
rRd = 1;
stat = stat+1;
end
2'b11:
begin
rRd = 0; //开始RGB读取时序
rCs = 0;
rWr = 1;
stat = 0;
end
endcase
end
end
endmodule
以上代码,我可以通过语法检查,也能通过综合,但是综合后的时序不正确,写入fpga后执行也不正确
我实在检查不出代码的错误在什么地方,请各位帮我分析分析
|
|