⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wb_lpc_periph.v

📁 Wishbone to LPC (Low-Pin Count) Bridge, includes master and slave modules. Supports 8-bit I/O Read a
💻 V
📖 第 1 页 / 共 2 页
字号:
                        state <= `LPC_ST_SIZE;                    end                `LPC_ST_SIZE:                    begin                        case(lad_i)                            4'h0:    xfr_len <= 3'b001;                            4'h1:    xfr_len <= 3'b010;                            4'h2:    xfr_len <= 3'b100;   // Firmware transfer uses '2' for 4-byte transfer.                            4'h3:    xfr_len <= 3'b100;   // DMA uses '3' for 4-byte transfer.                            default: xfr_len <= 3'b001;                        endcase                        if(lpc_write)                            state <= `LPC_ST_H_DATA;                        else                            state <= `LPC_ST_H_TAR1;                    end                `LPC_ST_H_DATA:                    begin                        case(dat_cnt)                            4'h0: lpc_dat_o[ 3: 0] <= lad_i;                            4'h1: lpc_dat_o[ 7: 4] <= lad_i;                            4'h2: lpc_dat_o[11: 8] <= lad_i;                            4'h3: lpc_dat_o[15:12] <= lad_i;                            4'h4: lpc_dat_o[19:16] <= lad_i;                            4'h5: lpc_dat_o[23:20] <= lad_i;                            4'h6: lpc_dat_o[27:24] <= lad_i;                            4'h7: lpc_dat_o[31:28] <= lad_i;                        endcase                                                dat_cnt <= dat_cnt + 1;                                                if(nibble_cnt == 1'b1) // end of byte                            begin                                if((fw_xfr) && (byte_cnt != xfr_len-1)) // Firmware transfer does not have TAR between bytes.                                    state <= `LPC_ST_H_DATA;										  else                                    state <= `LPC_ST_H_TAR1;                            end                        else                            state <= `LPC_ST_H_DATA;                            end                        `LPC_ST_H_TAR1:                    begin                        // It is ok to start the Wishbone Cycle, done below...                        state <= `LPC_ST_H_TAR2;                    end                `LPC_ST_H_TAR2:                    begin                        state <= (fw_xfr & lpc_write) ? `LPC_ST_FWW_SYNC : `LPC_ST_SYNC;                        lad_o <= (fw_xfr & lpc_write) ? `LPC_SYNC_READY : `LPC_SYNC_SWAIT;                        lad_oe <= 1'b1;     // start driving LAD                    end                `LPC_ST_SYNC:                    begin                        lad_oe <= 1'b1;     // start driving LAD                        // First byte of WB read, last byte of WB write                        if(((byte_cnt == xfr_len) & lpc_write) | ((byte_cnt == 0) & ~lpc_write)) begin                            // Errors can not be signalled for Firmware Memory accesses according to the spec.                            if((wbm_err_i) && (~fw_xfr)) begin                                dat_cnt <= { xfr_len, 1'b1 }; // Abort remainder of transfer                                lad_o <= `LPC_SYNC_ERROR;   // Bus error                                state <= `LPC_ST_P_TAR1;                            end else if(got_ack) begin                                if(lpc_write) begin                                    lad_o <= `LPC_SYNC_READY;   // Ready                                    state <= `LPC_ST_P_TAR1;                                end                                else begin                                    // READY+MORE for multi-byte DMA, except the final byte.                                    // For non-DMA cycles, only READY                                    lad_o <= (((xfr_len == 1) & ~lpc_write) || (~dma_xfr)) ? `LPC_SYNC_READY : `LPC_SYNC_MORE;                                    state <= `LPC_ST_P_DATA;                                end                            end                            else begin                                state <= `LPC_ST_SYNC;                                lad_o <= `LPC_SYNC_SWAIT;                            end                        end                        else begin  // Multi-byte transfer, just ack right away.                            if(lpc_write) begin                                lad_o <= (dma_xfr) ? `LPC_SYNC_MORE : `LPC_SYNC_READY;                                state <= `LPC_ST_P_TAR1;                            end									 else begin                                lad_o <= ((byte_cnt == xfr_len-1) || (~dma_xfr)) ? `LPC_SYNC_READY : `LPC_SYNC_MORE;   // Ready-More									                                 state <= `LPC_ST_P_DATA;                            end                        end                    end                `LPC_ST_FWW_SYNC:	// Firmware write requires a special SYNC without wait-states.                    begin                        lad_o <= 4'hF;                        state <= `LPC_ST_P_TAR2;                    end                        `LPC_ST_P_DATA:                    begin                        case(dat_cnt)                            4'h0: lad_o <= lpc_dat_i[ 3: 0];                            4'h1: lad_o <= lpc_dat_i[ 7: 4];                            4'h2: lad_o <= lpc_dat_i[11: 8];                            4'h3: lad_o <= lpc_dat_i[15:12];                            4'h4: lad_o <= lpc_dat_i[19:16];                            4'h5: lad_o <= lpc_dat_i[23:20];                            4'h6: lad_o <= lpc_dat_i[27:24];                            4'h7: lad_o <= lpc_dat_i[31:28];                        endcase                                                dat_cnt <= dat_cnt + 1;                                                if(nibble_cnt == 1'b1)  // Byte transfer complete                            if (byte_cnt == xfr_len-1) // Byte transfer complete                                state <= `LPC_ST_P_TAR1;                            else begin                                if(fw_xfr) // Firmware transfer does not have TAR between bytes.                                    state <= `LPC_ST_P_DATA;                                else                                    state <= `LPC_ST_SYNC;                            end                        else                            state <= `LPC_ST_P_DATA;                                lad_oe <= 1'b1;                    end                `LPC_ST_P_TAR1:                    begin                        lad_oe <= 1'b1;                        lad_o <= 4'hF;                        state <= `LPC_ST_P_TAR2;                    end                `LPC_ST_P_TAR2:                    begin                        lad_oe <= 1'b0;     // float LAD                        if(byte_cnt == xfr_len) begin                            state <= `LPC_ST_IDLE;                        end                        else begin                            if(lpc_write) begin  // DMA READ (Host to Peripheral)                                state <= `LPC_ST_P_WAIT1;                            end                            else begin  // unhandled READ case                                state <= `LPC_ST_IDLE;                            end                        end                    end                    `LPC_ST_P_WAIT1:                         state <= `LPC_ST_H_DATA;            endcase        end// The goal here is to split the Wishbone cycle handling out of the main state-machine// so it can run independently.  This is needed so that in the case of a firmware write,// where the FLASH requires wait-states (which are not allowed for FW write according to// the LPC Specification.)  In this case, since the FLASH cannot insert wait-states,// a subsequent LPC operation (which must not be another FW Write) will insert wait-// states before starting the next Wishbone master cycle.//// The only reason that I can think of for the LPC spec to mandate that Firmware Writes// must not insert wait-states is that since FLASH writes can take a very long time,// the LPC spec disallowed them to force LPC FLASH programming software to use polling// to determine when the write is complete rather than inserting a bunch of wait-states,// which would use up too much LPC bus bandwidth, and block other requests from getting// through.//        if(~nrst_i)        begin            wbm_adr_o <= 32'h00000000;            wbm_dat_o <= 32'h00000000;            wbm_stb_o <= 1'b0;            wbm_cyc_o <= 1'b0;            wbm_we_o <= 1'b0;            wbm_sel_o <= 4'b0000;            wbm_tga_o <= `WB_TGA_MEM;            got_ack <= 1'b0;        end        else begin            if ((state == `LPC_ST_H_TAR1) && (((byte_cnt == xfr_len) & lpc_write) | ((byte_cnt == 0) & ~lpc_write)))            begin                // Start Wishbone Cycle                wbm_stb_o <= 1'b1;                wbm_cyc_o <= 1'b1;                wbm_adr_o <= lpc_adr_reg;                wbm_dat_o <= lpc_dat_o;					                 wbm_we_o <= lpc_write;                wbm_tga_o <= lpc_tga_o;                got_ack <= 1'b0;                case(xfr_len)                    3'h0: wbm_sel_o <= `WB_SEL_BYTE;                    3'h2: wbm_sel_o <= `WB_SEL_SHORT;                    3'h4: wbm_sel_o <= `WB_SEL_WORD;                endcase            end            else if((wbm_stb_o == 1'b1) && (wbm_ack_i == 1'b1)) begin                // End Wishbone Cycle                wbm_stb_o <= 1'b0;                wbm_cyc_o <= 1'b0;                wbm_we_o <= 1'b0;                got_ack <= 1'b1;                if(~wbm_we_o) begin                    lpc_dat_i <= wbm_dat_i;                end             end        end    endendmodule                            

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -