Nexus 发表于 2014-1-24 09:36:02

FSMC如何又能读又能写

想做STM32F407+FPGA的控制板,目前用FSMC模拟SRAM接口通信,FPGA里面模拟成几个地址的寄存器,但是现在出现问题,发现寄存器只读或者只写好搞的,但是要可读可写的就比较麻烦了。Verilog掌握的不熟,还请赐教。如何写才能实现可读可写,inout类型感觉一般用在接口上,不用在内部,请提供些思路~~~
下面是我写的fsmc代码,也参考了不少论坛里面的大师。
module fsmc(
        addressbus,                        //Address Bus
        databus,                                //Data Bus
        wrn,                                        //write enable
        rdn,                                        //read enable
        csn,                                        //Chip select
        resetn,                                //Reset
                                                        //Registers
        INV_PWMA1P_R,                //PWMA1+
        INV_PWMA1P_W,               
        INV_PWMA1N_R,                //PWMA1-
        INV_PWMA1N_W,
        INV_PWMA2P_R,                //PWMA2+
        INV_PWMA2P_W,
        INV_PWMA2N_R,                //PWMA2-
        INV_PWMA2N_W,
        INV_PWMB1P_R,                //PWMB1+
        INV_PWMB1P_W,
        INV_PWMB1N_R,                //PWMB1-
        INV_PWMB1N_W,
        INV_PWMB2P_R,                //PWMB2+
        INV_PWMB2P_W,
        INV_PWMB2N_R,                //PWMB2-
        INV_PWMB2N_W,
        INV_PWMC1P_R,                //PWMC1+
        INV_PWMC1P_W,
        INV_PWMC1N_R,                //PWMC1-
        INV_PWMC1N_W,
        INV_PWMC2P_R,                //PWMC2+
        INV_PWMC2P_W,
        INV_PWMC2N_R,                //PWMC2-
        INV_PWMC2N_W
);

input                                addressbus;
inout                                databus;
input                                                wrn;
input                                                rdn;
input                                                csn;
input                                                resetn;

input                                INV_PWMA1P_R;                //PWMA1+
output                        INV_PWMA1P_W;
reg                                INV_PWMA1P_W;
               
input                                INV_PWMA1N_R;                //PWMA1-
output                        INV_PWMA1N_W;
reg                                INV_PWMA1N_W;       

input                                INV_PWMA2P_R;                //PWMA2+
output                        INV_PWMA2P_W;
reg                                INV_PWMA2P_W;       

input                                INV_PWMA2N_R;                //PWMA2-
output                        INV_PWMA2N_W;
reg                                INV_PWMA2N_W;       

input                                INV_PWMB1P_R;                //PWMB1+
output                        INV_PWMB1P_W;
reg                                INV_PWMB1P_W;       

input                                INV_PWMB1N_R;                //PWMB1-
output                        INV_PWMB1N_W;
reg                                INV_PWMB1N_W;       

input                                INV_PWMB2P_R;                //PWMB2+
output                        INV_PWMB2P_W;
reg                                INV_PWMB2P_W;       

input                                INV_PWMB2N_R;                //PWMB2-
output                        INV_PWMB2N_W;
reg                                INV_PWMB2N_W;       

input                                INV_PWMC1P_R;                //PWMC1+
output                        INV_PWMC1P_W;
reg                                INV_PWMC1P_W;       

input                                INV_PWMC1N_R;                //PWMC1-
output                        INV_PWMC1N_W;
reg                                INV_PWMC1N_W;       

input                                INV_PWMC2P_R;                //PWMC2+
output                        INV_PWMC2P_W;
reg                                INV_PWMC2P_W;       

input                                INV_PWMC2N_R;                //PWMC2-
output                        INV_PWMC2N_W;
reg                                INV_PWMC2N_W;       
                               
wire                                                rd;
wire                                                wr;

reg                                indata;

assign        rd = !(csn & rdn);
assign        wr = !(csn & wrn);
assign        reset = !resetn;
assign        databus = rd?indata:16'hzzzz;

//read operation
always @(rd or reset)
begin
        if(reset)indata <= 16'h0000;
        else
        begin
                case (addressbus)
                        6'b000000:        indata <= INV_PWMA1P_R;
                        6'b000001:        indata <= INV_PWMA1N_R;
                        6'b000010:        indata <= INV_PWMA2P_R;
                        6'b000011:        indata <= INV_PWMA2N_R;
                        6'b000100:        indata <= INV_PWMB1P_R;
                        6'b000101:        indata <= INV_PWMB1N_R;
                        6'b000110:        indata <= INV_PWMB2P_R;
                        6'b000111:        indata <= INV_PWMB2N_R;
                        6'b001000:        indata <= INV_PWMC1P_R;
                        6'b001001:        indata <= INV_PWMC1N_R;
                        6'b001010:        indata <= INV_PWMC2P_R;
                        6'b001011:        indata <= INV_PWMC2N_R;
                        default:;
                endcase
        end
end

//write operation
always @(negedge wr or posedge reset)
begin
        if(reset)
        begin
                INV_PWMA1P_W <= 16'h0000;
                INV_PWMA1N_W <= 16'h0000;
                INV_PWMA2P_W <= 16'h0000;
                INV_PWMA2N_W <= 16'h0000;
                INV_PWMB1P_W <= 16'h0000;
                INV_PWMB1N_W <= 16'h0000;
                INV_PWMB2P_W <= 16'h0000;
                INV_PWMB2N_W <= 16'h0000;
                INV_PWMC1P_W <= 16'h0000;
                INV_PWMC1N_W <= 16'h0000;
                INV_PWMC2P_W <= 16'h0000;
                INV_PWMC2N_W <= 16'h0000;
        end
        else
        begin
                case (addressbus)
                        6'b000000:        INV_PWMA1P_W <= databus;
                        6'b000001:        INV_PWMA1N_W <= databus;
                        6'b000010:        INV_PWMA2P_W <= databus;
                        6'b000011:        INV_PWMA2N_W <= databus;
                        6'b000100:        INV_PWMB1P_W <= databus;
                        6'b000101:        INV_PWMB1N_W <= databus;
                        6'b000110:        INV_PWMB2P_W <= databus;
                        6'b000111:        INV_PWMB2N_W <= databus;
                        6'b001000:        INV_PWMC1P_W <= databus;
                        6'b001001:        INV_PWMC1N_W <= databus;
                        6'b001010:        INV_PWMC2P_W <= databus;
                        6'b001011:        INV_PWMC2N_W <= databus;
                endcase
        end
end

endmodule

Nexus 发表于 2014-1-24 09:37:07

INV_PWMA1P_W ,INV_PWMA1P_R两个应该指的是同一寄存器,问题就在这,怎么把这两个连起来。。。

jiaowoxiaolu 发表于 2014-1-24 10:10:25

简单的方法,用fpga内部的m4k,m9k之类的做一个双口ram,fpga和cpu都通过这个ram交换数据就行了

Nexus 发表于 2014-1-24 11:36:49

jiaowoxiaolu 发表于 2014-1-24 10:10
简单的方法,用fpga内部的m4k,m9k之类的做一个双口ram,fpga和cpu都通过这个ram交换数据就行了 ...

也就是说,mcu能读写这块ram,fpga也可以的咯?主要是我也想了解下在这种情况下,verilog是如何操作的。

eaglefanxp 发表于 2014-1-26 15:49:26

我做过读写寄存器的,用三态门就行

Nexus 发表于 2014-1-26 22:12:36

eaglefanxp 发表于 2014-1-26 15:49
我做过读写寄存器的,用三态门就行

三态门只用在接口上,如果要封装到里面的话,好像不太方便。

zxq6 发表于 2014-1-27 09:09:13

可以的,一句话的事
页: [1]
查看完整版本: FSMC如何又能读又能写