OpenCores
URL https://opencores.org/ocsvn/wb_lpc/wb_lpc/trunk

Subversion Repositories wb_lpc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/trunk/rtl/verilog/wb_lpc_defines.v
37,45 → 37,46
 
// Wishbone LPC Master/Slave Interface Definitions
 
`define LPC_START 4'b0000
`define LPC_STOP 4'b1111
`define LPC_FW_READ 4'b1101
`define LPC_FW_WRITE 4'b1110
`define LPC_START 4'b0000
`define LPC_STOP 4'b1111
`define LPC_FW_READ 4'b1101
`define LPC_FW_WRITE 4'b1110
 
`define LPC_SYNC_READY 4'b0000 // LPC Sync Ready
`define LPC_SYNC_SWAIT 4'b0101 // LPC Sync Short Wait
`define LPC_SYNC_LWAIT 4'b0110 // LPC Sync Long Wait
`define LPC_SYNC_MORE 4'b1001 // LPC Sync Ready More (DMA only)
`define LPC_SYNC_ERROR 4'b1010 // LPC Sync Error
`define LPC_SYNC_READY 4'b0000 // LPC Sync Ready
`define LPC_SYNC_SWAIT 4'b0101 // LPC Sync Short Wait
`define LPC_SYNC_LWAIT 4'b0110 // LPC Sync Long Wait
`define LPC_SYNC_MORE 4'b1001 // LPC Sync Ready More (DMA only)
`define LPC_SYNC_ERROR 4'b1010 // LPC Sync Error
 
`define LPC_ST_IDLE 13'h000 // LPC Idle state
`define LPC_ST_START 13'h001 // LPC Start state
`define LPC_ST_CYCTYP 13'h002 // LPC Cycle Type State
`define LPC_ST_ADDR 13'h004 // LPC Address state (4 cycles)
`define LPC_ST_CHAN 13'h008 // LPC Address state (4 cycles)
`define LPC_ST_SIZE 13'h010 // LPC Address state (4 cycles)
`define LPC_ST_H_DATA 13'h020 // LPC Host Data state (2 cycles)
`define LPC_ST_P_DATA 13'h040 // LPC Peripheral Data state (2 cycles)
`define LPC_ST_H_TAR1 13'h080 // LPC Host Turnaround 1 (Drive LAD 4'hF)
`define LPC_ST_H_TAR2 13'h100 // LPC Host Turnaround 2 (Float LAD)
`define LPC_ST_P_TAR1 13'h200 // LPC Peripheral Turnaround 1 (Drive LAD = 4'hF)
`define LPC_ST_P_TAR2 13'h400 // LPC Peripheral Turnaround 2 (Float LAD)
`define LPC_ST_SYNC 13'h800 // LPC Sync State (may be multiple cycles for wait-states)
`define LPC_ST_P_WAIT1 13'h1000 // LPC Sync State (may be multiple cycles for wait-states)
`define LPC_ST_IDLE 13'h000 // LPC Idle state
`define LPC_ST_START 13'h001 // LPC Start state
`define LPC_ST_CYCTYP 13'h002 // LPC Cycle Type State
`define LPC_ST_ADDR 13'h004 // LPC Address state (4 cycles)
`define LPC_ST_CHAN 13'h008 // LPC Address state (4 cycles)
`define LPC_ST_SIZE 13'h010 // LPC Address state (4 cycles)
`define LPC_ST_H_DATA 13'h020 // LPC Host Data state (2 cycles)
`define LPC_ST_P_DATA 13'h040 // LPC Peripheral Data state (2 cycles)
`define LPC_ST_H_TAR1 13'h080 // LPC Host Turnaround 1 (Drive LAD 4'hF)
`define LPC_ST_H_TAR2 13'h100 // LPC Host Turnaround 2 (Float LAD)
`define LPC_ST_P_TAR1 13'h200 // LPC Peripheral Turnaround 1 (Drive LAD = 4'hF)
`define LPC_ST_P_TAR2 13'h400 // LPC Peripheral Turnaround 2 (Float LAD)
`define LPC_ST_WB_RETIRE 13'h400 // Retire Wishbone transfer (Host only), ends WB cycle.
`define LPC_ST_SYNC 13'h800 // LPC Sync State (may be multiple cycles for wait-states)
`define LPC_ST_P_WAIT1 13'h1000 // LPC Sync State (may be multiple cycles for wait-states)
 
 
`define WB_SEL_BYTE 4'b0001 // Byte Transfer
`define WB_SEL_SHORT 4'b0011 // Short Transfer
`define WB_SEL_WORD 4'b1111 // Word Transfer
`define WB_SEL_BYTE 4'b0001 // Byte Transfer
`define WB_SEL_SHORT 4'b0011 // Short Transfer
`define WB_SEL_WORD 4'b1111 // Word Transfer
 
`define WB_TGA_MEM 2'b00 // Memory Cycle
`define WB_TGA_IO 2'b01 // I/O Cycle
`define WB_TGA_FW 2'b10 // Firmware Cycle
`define WB_TGA_DMA 2'b11 // DMA Cycle
`define WB_TGA_MEM 2'b00 // Memory Cycle
`define WB_TGA_IO 2'b01 // I/O Cycle
`define WB_TGA_FW 2'b10 // Firmware Cycle
`define WB_TGA_DMA 2'b11 // DMA Cycle
 
// LDRQ States
 
`define LDRQ_ST_IDLE 4'h0
`define LDRQ_ST_ADDR 4'h1
`define LDRQ_ST_ACT 4'h2
`define LDRQ_ST_DONE 4'h4
`define LDRQ_ST_IDLE 4'h0
`define LDRQ_ST_ADDR 4'h1
`define LDRQ_ST_ACT 4'h2
`define LDRQ_ST_DONE 4'h4
/trunk/rtl/verilog/wb_lpc_host.v
1,6 → 1,6
//////////////////////////////////////////////////////////////////////
//// ////
//// $Id: wb_lpc_host.v,v 1.1 2008-03-02 20:46:40 hharte Exp $
//// $Id: wb_lpc_host.v,v 1.2 2008-03-05 05:50:25 hharte Exp $ ////
//// wb_lpc_host.v - Wishbone Slave to LPC Host Bridge ////
//// ////
//// This file is part of the Wishbone LPC Bridge project ////
40,323 → 40,328
 
`include "../../rtl/verilog/wb_lpc_defines.v"
 
// I/O Write I/O Read DMA Read DMA Write
//
// States - 1. H Start H Start H Start H Start
// 2. H CYCTYPE+DIR H CYCTYPE+DIR H CYCTYPE+DIR H CYCTYPE+DIR
// 3. H Addr (4) H Addr (4) H CHAN+TC H CHAN+TC
// H SIZE H SIZE
// 4. H Data (2) H TAR (2) +-H DATA (2) H TAR (2)
// 5. H TAR (2) P SYNC (1+) | H TAR (2) +-P SYNC (1+)
// 6. P SYNC (1+) P DATA (2) | H SYNC (1+) +-P DATA (2)
// 7. P TAR (2) P TAR (2) +-P TAR (2) P TAR
//
// I/O Write I/O Read DMA Read DMA Write
//
// States - 1. H Start H Start H Start H Start
// 2. H CYCTYPE+DIR H CYCTYPE+DIR H CYCTYPE+DIR H CYCTYPE+DIR
// 3. H Addr (4) H Addr (4) H CHAN+TC H CHAN+TC
// H SIZE H SIZE
// 4. H Data (2) H TAR (2) +-H DATA (2) H TAR (2)
// 5. H TAR (2) P SYNC (1+) | H TAR (2) +-P SYNC (1+)
// 6. P SYNC (1+) P DATA (2) | H SYNC (1+) +-P DATA (2)
// 7. P TAR (2) P TAR (2) +-P TAR (2) P TAR
//
module wb_lpc_host(clk_i, nrst_i, wbs_adr_i, wbs_dat_o, wbs_dat_i, wbs_sel_i, wbs_tga_i, wbs_we_i,
wbs_stb_i, wbs_cyc_i, wbs_ack_o,
dma_chan_i, dma_tc_i,
lframe_o, lad_i, lad_o, lad_oe
wbs_stb_i, wbs_cyc_i, wbs_ack_o,
dma_chan_i, dma_tc_i,
lframe_o, lad_i, lad_o, lad_oe
);
// Wishbone Slave Interface
input clk_i;
input nrst_i; // Active low reset.
input [31:0] wbs_adr_i;
output [31:0] wbs_dat_o;
input [31:0] wbs_dat_i;
input [3:0] wbs_sel_i;
input [1:0] wbs_tga_i;
input wbs_we_i;
input wbs_stb_i;
input wbs_cyc_i;
output reg wbs_ack_o;
// LPC Master Interface
output reg lframe_o; // LPC Frame output (active high)
output reg lad_oe; // LPC AD Output Enable
input [3:0] lad_i; // LPC AD Input Bus
output reg [3:0] lad_o; // LPC AD Output Bus
// Wishbone Slave Interface
input clk_i;
input nrst_i; // Active low reset.
input [31:0] wbs_adr_i;
output [31:0] wbs_dat_o;
input [31:0] wbs_dat_i;
input [3:0] wbs_sel_i;
input [1:0] wbs_tga_i;
input wbs_we_i;
input wbs_stb_i;
input wbs_cyc_i;
output reg wbs_ack_o;
// LPC Master Interface
output reg lframe_o; // LPC Frame output (active high)
output reg lad_oe; // LPC AD Output Enable
input [3:0] lad_i; // LPC AD Input Bus
output reg [3:0] lad_o; // LPC AD Output Bus
 
// DMA-Specific sideband signals
input [2:0] dma_chan_i; // DMA Channel
input dma_tc_i; // DMA Terminal Count
// DMA-Specific sideband signals
input [2:0] dma_chan_i; // DMA Channel
input dma_tc_i; // DMA Terminal Count
 
reg [12:0] state; // Current state
reg [2:0] adr_cnt; // Address nibbe counter
reg [3:0] dat_cnt; // Data nibble counter
reg [2:0] xfr_len; // Number of nibbls for transfer
wire [2:0] byte_cnt = dat_cnt[3:1]; // Byte Counter
wire nibble_cnt = dat_cnt[0]; // Nibble counter
reg [31:0] lpc_dat_i; // Temporary storage for input word.
reg [12:0] state; // Current state
reg [2:0] adr_cnt; // Address nibbe counter
reg [3:0] dat_cnt; // Data nibble counter
reg [2:0] xfr_len; // Number of nibbls for transfer
wire [2:0] byte_cnt = dat_cnt[3:1]; // Byte Counter
wire nibble_cnt = dat_cnt[0]; // Nibble counter
reg [31:0] lpc_dat_i; // Temporary storage for input word.
 
//
// generate wishbone register signals
wire wbs_acc = wbs_cyc_i & wbs_stb_i; // Wishbone access
wire wbs_wr = wbs_acc & wbs_we_i; // Wishbone write access
//
// generate wishbone register signals
wire wbs_acc = wbs_cyc_i & wbs_stb_i; // Wishbone access
wire wbs_wr = wbs_acc & wbs_we_i; // Wishbone write access
 
// Memory Cycle (tga== 1'b00) is bit 2=1 for LPC Cycle Type.
wire mem_xfr = (wbs_tga_i == `WB_TGA_MEM);
wire dma_xfr = (wbs_tga_i == `WB_TGA_DMA);
wire fw_xfr = (wbs_tga_i == `WB_TGA_FW);
assign wbs_dat_o[31:0] = lpc_dat_i;
// Memory Cycle (tga== 1'b00) is bit 2=1 for LPC Cycle Type.
wire mem_xfr = (wbs_tga_i == `WB_TGA_MEM);
wire dma_xfr = (wbs_tga_i == `WB_TGA_DMA);
wire fw_xfr = (wbs_tga_i == `WB_TGA_FW);
assign wbs_dat_o[31:0] = lpc_dat_i;
 
always @(posedge clk_i or negedge nrst_i)
if(~nrst_i)
begin
state <= `LPC_ST_IDLE;
lframe_o <= 1'b0;
wbs_ack_o <= 1'b0;
lad_oe <= 1'b0;
lad_o <= 4'b0;
adr_cnt <= 3'b0;
dat_cnt <= 4'h0;
xfr_len <= 3'b000;
lpc_dat_i <= 32'h00000000;
end
else begin
case(state)
`LPC_ST_IDLE:
begin
wbs_ack_o <= 1'b0;
lframe_o <= 1'b0;
dat_cnt <= 4'h0;
always @(posedge clk_i or negedge nrst_i)
if(~nrst_i)
begin
state <= `LPC_ST_IDLE;
lframe_o <= 1'b0;
wbs_ack_o <= 1'b0;
lad_oe <= 1'b0;
lad_o <= 4'b0;
adr_cnt <= 3'b0;
dat_cnt <= 4'h0;
xfr_len <= 3'b000;
lpc_dat_i <= 32'h00000000;
end
else begin
case(state)
`LPC_ST_IDLE:
begin
wbs_ack_o <= 1'b0;
lframe_o <= 1'b0;
dat_cnt <= 4'h0;
 
if(wbs_acc) // Wishbone access starts LPC transaction
state <= `LPC_ST_START;
else
state <= `LPC_ST_IDLE;
end
`LPC_ST_START:
begin
lframe_o <= 1'b1;
if(~fw_xfr) begin // For Memory and I/O Cycles
lad_o <= `LPC_START;
state <= `LPC_ST_CYCTYP;
end
else begin // Firmware Read and Write Cycles
if(wbs_wr)
lad_o <= `LPC_FW_WRITE;
else
lad_o <= `LPC_FW_READ;
state <= `LPC_ST_ADDR;
end
lad_oe <= 1'b1;
adr_cnt <= ((mem_xfr | fw_xfr) ? 3'b000 : 3'b100);
end
`LPC_ST_CYCTYP:
begin
lframe_o <= 1'b0;
lad_oe <= 1'b1;
if(wbs_acc) // Wishbone access starts LPC transaction
state <= `LPC_ST_START;
else
state <= `LPC_ST_IDLE;
end
`LPC_ST_START:
begin
lframe_o <= 1'b1;
if(~fw_xfr) begin // For Memory and I/O Cycles
lad_o <= `LPC_START;
state <= `LPC_ST_CYCTYP;
end
else begin // Firmware Read and Write Cycles
if(wbs_wr)
lad_o <= `LPC_FW_WRITE;
else
lad_o <= `LPC_FW_READ;
state <= `LPC_ST_ADDR;
end
lad_oe <= 1'b1;
adr_cnt <= ((mem_xfr | fw_xfr) ? 3'b000 : 3'b100);
end
`LPC_ST_CYCTYP:
begin
lframe_o <= 1'b0;
lad_oe <= 1'b1;
 
if(~dma_xfr)
begin
lad_o <= {1'b0,mem_xfr,wbs_wr,1'b0}; // Cycle Type/Direction for I/O or MEM
state <= `LPC_ST_ADDR;
end
else // it is DMA
begin
lad_o <= {1'b1,1'b0,~wbs_wr,1'b0}; // Cycle Type/Direction for DMA, r/w is inverted for DMA
state <= `LPC_ST_CHAN;
end
end
`LPC_ST_ADDR: // Output four nubbles of address.
begin
lframe_o <= 1'b0; // In case we came here from a Firmware cycle, which skips CYCTYP.
// The LPC Bus Address is sent across the bus a nibble at a time;
// however, the most significant nibble is sent first. For firmware and
// memory cycles, the address is 32-bits. Actually, for memeory accesses,
// the most significant nibble is known as the IDSEL field. For I/O,
// the address is only 16-bits wide.
case(adr_cnt)
3'h0:
lad_o <= wbs_adr_i[31:28];
3'h1:
lad_o <= wbs_adr_i[27:24];
3'h2:
lad_o <= wbs_adr_i[23:20];
3'h3:
lad_o <= wbs_adr_i[19:16];
3'h4:
lad_o <= wbs_adr_i[15:12];
3'h5:
lad_o <= wbs_adr_i[11:8];
3'h6:
lad_o <= wbs_adr_i[7:4];
3'h7:
lad_o <= wbs_adr_i[3:0];
endcase
adr_cnt <= adr_cnt + 1;
if(adr_cnt == 4'h7) // Last address nibble.
begin
if(~fw_xfr)
if(wbs_wr)
state <= `LPC_ST_H_DATA;
else
state <= `LPC_ST_H_TAR1;
else // For firmware read/write, we need to transfer the MSIZE nibble
state <= `LPC_ST_SIZE;
end
else
state <= `LPC_ST_ADDR;
lad_oe <= 1'b1;
xfr_len <= 3'b001; // One Byte Transfer
end
`LPC_ST_CHAN:
begin
lad_o <= {dma_tc_i, dma_chan_i};
state <= `LPC_ST_SIZE;
end
`LPC_ST_SIZE:
begin
case(wbs_sel_i)
`WB_SEL_BYTE:
begin
xfr_len <= 3'b001;
lad_o <= 4'h0;
end
`WB_SEL_SHORT:
begin
xfr_len <= 3'b010;
lad_o <= 4'h1;
end
`WB_SEL_WORD:
begin
xfr_len <= 3'b100;
if(fw_xfr) // Firmware transfer uses '2' for 4-byte transfer.
lad_o <= 4'h2;
else // DMA uses '3' for 4-byte transfer.
lad_o <= 4'h3;
end
default:
begin
xfr_len <= 3'b001;
lad_o <= 4'h0;
end
endcase
if(wbs_wr)
state <= `LPC_ST_H_DATA;
else
state <= `LPC_ST_H_TAR1;
end
if(~dma_xfr)
begin
lad_o <= {1'b0,mem_xfr,wbs_wr,1'b0}; // Cycle Type/Direction for I/O or MEM
state <= `LPC_ST_ADDR;
end
else // it is DMA
begin
lad_o <= {1'b1,1'b0,~wbs_wr,1'b0}; // Cycle Type/Direction for DMA, r/w is inverted for DMA
state <= `LPC_ST_CHAN;
end
end
`LPC_ST_ADDR: // Output four nubbles of address.
begin
lframe_o <= 1'b0; // In case we came here from a Firmware cycle, which skips CYCTYP.
// The LPC Bus Address is sent across the bus a nibble at a time;
// however, the most significant nibble is sent first. For firmware and
// memory cycles, the address is 32-bits. Actually, for memeory accesses,
// the most significant nibble is known as the IDSEL field. For I/O,
// the address is only 16-bits wide.
case(adr_cnt)
3'h0:
lad_o <= wbs_adr_i[31:28];
3'h1:
lad_o <= wbs_adr_i[27:24];
3'h2:
lad_o <= wbs_adr_i[23:20];
3'h3:
lad_o <= wbs_adr_i[19:16];
3'h4:
lad_o <= wbs_adr_i[15:12];
3'h5:
lad_o <= wbs_adr_i[11:8];
3'h6:
lad_o <= wbs_adr_i[7:4];
3'h7:
lad_o <= wbs_adr_i[3:0];
endcase
adr_cnt <= adr_cnt + 1;
if(adr_cnt == 4'h7) // Last address nibble.
begin
if(~fw_xfr)
if(wbs_wr)
state <= `LPC_ST_H_DATA;
else
state <= `LPC_ST_H_TAR1;
else // For firmware read/write, we need to transfer the MSIZE nibble
state <= `LPC_ST_SIZE;
end
else
state <= `LPC_ST_ADDR;
lad_oe <= 1'b1;
xfr_len <= 3'b001; // One Byte Transfer
end
`LPC_ST_CHAN:
begin
lad_o <= {dma_tc_i, dma_chan_i};
state <= `LPC_ST_SIZE;
end
`LPC_ST_SIZE:
begin
case(wbs_sel_i)
`WB_SEL_BYTE:
begin
xfr_len <= 3'b001;
lad_o <= 4'h0;
end
`WB_SEL_SHORT:
begin
xfr_len <= 3'b010;
lad_o <= 4'h1;
end
`WB_SEL_WORD:
begin
xfr_len <= 3'b100;
if(fw_xfr) // Firmware transfer uses '2' for 4-byte transfer.
lad_o <= 4'h2;
else // DMA uses '3' for 4-byte transfer.
lad_o <= 4'h3;
end
default:
begin
xfr_len <= 3'b001;
lad_o <= 4'h0;
end
endcase
if(wbs_wr)
state <= `LPC_ST_H_DATA;
else
state <= `LPC_ST_H_TAR1;
end
 
`LPC_ST_H_DATA:
begin
lad_oe <= 1'b1;
case(dat_cnt) // We only support a single byte for I/O.
4'h0:
lad_o <= wbs_dat_i[3:0];
4'h1:
lad_o <= wbs_dat_i[7:4];
4'h2:
lad_o <= wbs_dat_i[11:8];
4'h3:
lad_o <= wbs_dat_i[15:12];
4'h4:
lad_o <= wbs_dat_i[19:16];
4'h5:
lad_o <= wbs_dat_i[23:20];
4'h6:
lad_o <= wbs_dat_i[27:24];
4'h7:
lad_o <= wbs_dat_i[31:28];
default:
lad_o <= 4'hx;
endcase
dat_cnt <= dat_cnt + 1;
if(nibble_cnt == 1'b1) // end of byte
begin
state <= `LPC_ST_H_TAR1;
end
else
state <= `LPC_ST_H_DATA;
end
`LPC_ST_H_TAR1:
begin
lad_o <= 4'b1111; // Drive LAD high
lad_oe <= 1'b1;
state <= `LPC_ST_H_TAR2;
end
`LPC_ST_H_TAR2:
begin
lad_oe <= 1'b0; // float LAD
state <= `LPC_ST_SYNC;
end
`LPC_ST_SYNC:
begin
lad_oe <= 1'b0; // float LAD
if(lad_i == `LPC_SYNC_READY) begin
if(wbs_wr) begin
state <= `LPC_ST_P_TAR1;
end
else
state <= `LPC_ST_P_DATA;
end
else
state <= `LPC_ST_SYNC;
end
`LPC_ST_P_DATA:
begin
case(dat_cnt)
4'h0:
lpc_dat_i[3:0] <= lad_i;
4'h1:
lpc_dat_i[7:4] <= lad_i;
4'h2:
lpc_dat_i[11:8] <= lad_i;
4'h3:
lpc_dat_i[15:12] <= lad_i;
4'h4:
lpc_dat_i[19:16] <= lad_i;
4'h5:
lpc_dat_i[23:20] <= lad_i;
4'h6:
lpc_dat_i[27:24] <= lad_i;
4'h7:
lpc_dat_i[31:28] <= lad_i;
endcase
dat_cnt <= dat_cnt + 1;
if(nibble_cnt == 1'b1) // Byte transfer complete
if (byte_cnt == xfr_len-1) // End of data transfer phase
state <= `LPC_ST_P_TAR1;
else
state <= `LPC_ST_SYNC;
else // Go to next nibble
state <= `LPC_ST_P_DATA;
end
`LPC_ST_P_TAR1:
begin
lad_oe <= 1'b0;
// 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;
wbs_ack_o <= wbs_acc;
end
else begin
if(wbs_wr) begin // DMA READ (Host to Peripheral)
state <= `LPC_ST_H_DATA;
end
else begin // unhandled READ case
state <= `LPC_ST_IDLE;
end
end
end
endcase
end
`LPC_ST_H_DATA:
begin
lad_oe <= 1'b1;
case(dat_cnt) // We only support a single byte for I/O.
4'h0:
lad_o <= wbs_dat_i[3:0];
4'h1:
lad_o <= wbs_dat_i[7:4];
4'h2:
lad_o <= wbs_dat_i[11:8];
4'h3:
lad_o <= wbs_dat_i[15:12];
4'h4:
lad_o <= wbs_dat_i[19:16];
4'h5:
lad_o <= wbs_dat_i[23:20];
4'h6:
lad_o <= wbs_dat_i[27:24];
4'h7:
lad_o <= wbs_dat_i[31:28];
default:
lad_o <= 4'hx;
endcase
dat_cnt <= dat_cnt + 1;
if(nibble_cnt == 1'b1) // end of byte
begin
state <= `LPC_ST_H_TAR1;
end
else
state <= `LPC_ST_H_DATA;
end
`LPC_ST_H_TAR1:
begin
lad_o <= 4'b1111; // Drive LAD high
lad_oe <= 1'b1;
state <= `LPC_ST_H_TAR2;
end
`LPC_ST_H_TAR2:
begin
lad_oe <= 1'b0; // float LAD
state <= `LPC_ST_SYNC;
end
`LPC_ST_SYNC:
begin
lad_oe <= 1'b0; // float LAD
if(lad_i == `LPC_SYNC_READY) begin
if(wbs_wr) begin
state <= `LPC_ST_P_TAR1;
end
else
state <= `LPC_ST_P_DATA;
end
else
state <= `LPC_ST_SYNC;
end
`LPC_ST_P_DATA:
begin
case(dat_cnt)
4'h0:
lpc_dat_i[3:0] <= lad_i;
4'h1:
lpc_dat_i[7:4] <= lad_i;
4'h2:
lpc_dat_i[11:8] <= lad_i;
4'h3:
lpc_dat_i[15:12] <= lad_i;
4'h4:
lpc_dat_i[19:16] <= lad_i;
4'h5:
lpc_dat_i[23:20] <= lad_i;
4'h6:
lpc_dat_i[27:24] <= lad_i;
4'h7:
lpc_dat_i[31:28] <= lad_i;
endcase
dat_cnt <= dat_cnt + 1;
if(nibble_cnt == 1'b1) // Byte transfer complete
if (byte_cnt == xfr_len-1) // End of data transfer phase
state <= `LPC_ST_P_TAR1;
else
state <= `LPC_ST_SYNC;
else // Go to next nibble
state <= `LPC_ST_P_DATA;
end
`LPC_ST_P_TAR1:
begin
lad_oe <= 1'b0;
if(byte_cnt == xfr_len) begin
state <= `LPC_ST_WB_RETIRE;
wbs_ack_o <= wbs_acc;
end
else begin
if(wbs_wr) begin // DMA READ (Host to Peripheral)
state <= `LPC_ST_H_DATA;
end
else begin // unhandled READ case
state <= `LPC_ST_IDLE;
end
end
end
`LPC_ST_WB_RETIRE:
begin
wbs_ack_o <= 1'b0;
if(wbs_acc) begin
state <= `LPC_ST_WB_RETIRE;
end
else begin
state <= `LPC_ST_IDLE;
end
end
endcase
end
 
endmodule
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.