高云SOC芯片GW1NSR-LV4CQN48的ARM总线

高云SOC芯片GW1NSR-LV4CQN48的ARM总线

         国产GOWIN高云出的一款芯片是GW1NSR-LV4CQN48PC7/I6,QN48封装,资源是4608,有10个18K BRAM,以及2个PLL,内置HyperRAM 64Mb, 可以用于电机,图像测试。内置ARM-M3硬核,可以替换简单的MCU应用。

        其中ARM和FPGA的总线连接是两种AHB和APB总线。以下介绍的基本总线的连接代码。

         其中AHB总线是包含BURST突发模式读取数据内容。实际从波形调试可以得到每次突发模式8个数据内容。

module Gowin_AHB_Multiple

(

         output      wire [31:0]        AHB_HRDATA,

         output      wire                    AHB_HREADY,

         output      wire [ 1:0]         AHB_HRESP,

         input         wire [ 1:0]  AHB_HTRANS,

         input         wire [ 2:0]  AHB_HBURST,

         input         wire [ 3:0]  AHB_HPROT,

         input         wire [ 2:0]         AHB_HSIZE,

         input         wire                    AHB_HWRITE,

         input         wire                    AHB_HMASTLOCK,

         input         wire [ 3:0]         AHB_HMASTER,

         input         wire [31:0]        AHB_HADDR,

         input         wire [31:0]  AHB_HWDATA,

         input         wire                    AHB_HSEL,

         input         wire                    AHB_HCLK,

         input         wire                    AHB_HRESETn

);

 

//The AHB BUS is always ready

assign AHB_HREADY = 1'b1; //ready signal, slave to MCU master

//Response OKAY

assign AHB_HRESP  = 2'b0;//response signal, slave to MCU master

 

//Define Reg for AHB BUS

reg [31:0]  ahb_address;

reg           ahb_control;

reg         ahb_sel;

reg         ahb_htrans;

 

always @(posedge AHB_HCLK or negedge AHB_HRESETn)

begin

         if(~AHB_HRESETn)

         begin

                   ahb_address  <= 32'b0;

                   ahb_control  <= 1'b0;

        ahb_sel      <= 1'b0;

        ahb_htrans   <= 1'b0;

         end

         else              //Select The AHB Device

         begin                             //Get the Address of reg

                   ahb_address  <= AHB_HADDR;

                   ahb_control  <= AHB_HWRITE;

        ahb_sel      <= AHB_HSEL;

        ahb_htrans   <= AHB_HTRANS[1];

         end

end

 

wire write_enable = ahb_htrans & ahb_control    & ahb_sel;

wire read_enable  = ahb_htrans & (!ahb_control) & ahb_sel;

 

//The register of Multiple AHB bus

reg [7:0 ] Multiplier;

reg [7:0 ] Multiplicand;

reg [15:0] The_result;

reg [1:0 ] Cmd_reg; //The Bit0 -> Start

                    //The Bit1 -> The State of Multiple

 

wire        cmd_finished_status ;

wire [15:0] wire_multiple_result;

 

//write data to AHB bus

always @(posedge AHB_HCLK or negedge AHB_HRESETn)

begin

         if(~AHB_HRESETn)

         begin

                    Multiplier   <= 8'b0;

                    Multiplicand <= 8'b0;

         end

         else if(write_enable)

         begin

                   case (ahb_address[15:0])

                   16'h0000: Multiplier       <= AHB_HWDATA[7:0];

                   16'h0004: Multiplicand  <= AHB_HWDATA[7:0];

                   endcase

         end

end

 

//Status

always @(posedge AHB_HCLK or negedge AHB_HRESETn)

begin

         if(~AHB_HRESETn)

         begin

                   Cmd_reg  <=  2'b0;

         end

         else if(write_enable &(ahb_address[15:0] == 16'h0008))

         begin

                   Cmd_reg  <= AHB_HWDATA[1:0];

         end

         else if(cmd_finished_status)

         begin

                   Cmd_reg  <=  2'b10;

         end

end

 

//read data to AHB bus

always @(posedge AHB_HCLK or negedge AHB_HRESETn)

begin

    if(~AHB_HRESETn)

    begin

        The_result     <=    16'b0;

    end

    else if(cmd_finished_status)

    begin

       The_result      <=     wire_multiple_result;

    end

end

 

//register address

reg [31:0] ahb_rdata;

 

always @(*)

begin

         if(read_enable)  //read cmd

         begin

                   case (ahb_address[15:0])

                   32'h0000:  ahb_rdata = Multiplier;

                   32'h0004:  ahb_rdata = Multiplicand;

                   32'h0008:  ahb_rdata = Cmd_reg;

                   32'h000C:  ahb_rdata = The_result;

                   default:ahb_rdata = 32'hFFFFFFFF;

                   endcase

         end

    else

    begin

        ahb_rdata = 32'hFFFFFFFF;

    end

end

 

assign AHB_HRDATA = ahb_rdata;

 

而对于APB的总线,一次性只能读取一个数据内容。

module Gowin_APB2_Multiple

(

    //---------------------The Port declartion--------

    input          pclk,       // master clock input

    input          presetn,    //synchronous active low reset   

    input          psel,       //slave sel

    input          penable,    //enable

    input          pwrite,     //transmit direction

    input   [11:2] paddr,      //lower address bits

    input   [31:0] pwdata,     //write data

    output  [31:0] prdata      //read data

);

 

wire write_enable = psel    & pwrite    & (!penable);

wire read_enable  = psel    & (!pwrite) &   penable;

 

//The register of apb bus

reg [7:0 ] Multiplier;

reg [7:0 ] Multiplicand;

reg [15:0] The_result;

reg [1:0 ] Cmd_reg; //The Bit0 -> Start

                    //The Bit1 -> The State of Multiple

 

//write Block

always @(posedge pclk or negedge presetn)

begin

    if(~presetn)

    begin

        Multiplier      <=  8'b0;

        Multiplicand    <=  8'b0;

    end

    else

    begin

        if(write_enable)

        begin

            case (paddr[11:2])

            10'h00: Multiplier      <= pwdata;

            10'h01: Multiplicand    <= pwdata;

            endcase

        end

    end

end

 

reg [31:0] prdata_out;

//Read Block

always @(*)

begin

    if (read_enable)

    begin

        case (paddr[11:2])

        10'h00:  prdata_out = Multiplier;

        10'h01:  prdata_out = Multiplicand;

        10'h02:  prdata_out = Cmd_reg;

        10'h03:  prdata_out = The_result;

        default: prdata_out = 32'hFFFFFFFF;//Indicate the unvalid state

        endcase

    end

    else

    begin

        prdata_out  = 32'hFFFFFFFF;

    end

end

 

assign prdata = prdata_out;

 

 

posted on 2023-05-17 15:39  szfpga  阅读(447)  评论(0编辑  收藏  举报