//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// $Id: wb_lpc_periph.v,v 1.1 2008-03-02 20:46:40 hharte Exp $
|
//// $Id: wb_lpc_periph.v,v 1.2 2008-03-05 05:50:59 hharte Exp $ ////
|
//// wb_lpc_periph.v - LPC Peripheral to Wishbone Master Bridge ////
|
//// wb_lpc_periph.v - LPC Peripheral to Wishbone Master Bridge ////
|
//// ////
|
//// ////
|
//// This file is part of the Wishbone LPC Bridge project ////
|
//// This file is part of the Wishbone LPC Bridge project ////
|
//// http://www.opencores.org/projects/wb_lpc/ ////
|
//// http://www.opencores.org/projects/wb_lpc/ ////
|
//// ////
|
//// ////
|
//// Author: ////
|
//// Author: ////
|
//// - Howard M. Harte (hharte@opencores.org) ////
|
//// - Howard M. Harte (hharte@opencores.org) ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2008 Howard M. Harte ////
|
//// Copyright (C) 2008 Howard M. Harte ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
`timescale 1 ns / 1 ns
|
`timescale 1 ns / 1 ns
|
|
|
`include "../../rtl/verilog/wb_lpc_defines.v"
|
`include "../../rtl/verilog/wb_lpc_defines.v"
|
|
|
// I/O Write I/O Read DMA Read DMA Write
|
// I/O Write I/O Read DMA Read DMA Write
|
//
|
//
|
// States - 1. H Start H Start H Start H Start
|
// States - 1. H Start H Start H Start H Start
|
// 2. H CYCTYPE+DIR H CYCTYPE+DIR H CYCTYPE+DIR H CYCTYPE+DIR
|
// 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
|
// 3. H Addr (4) H Addr (4) H CHAN+TC H CHAN+TC
|
// H SIZE H SIZE
|
// H SIZE H SIZE
|
// 4. H Data (2) H TAR (2) +-H DATA (2) H TAR (2)
|
// 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+)
|
// 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)
|
// 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
|
// 7. P TAR (2) P TAR (2) +-P TAR (2) P TAR
|
//
|
//
|
|
|
module wb_lpc_periph(clk_i, nrst_i, wbm_adr_o, wbm_dat_o, wbm_dat_i, wbm_sel_o, wbm_tga_o, wbm_we_o,
|
module wb_lpc_periph(clk_i, nrst_i, wbm_adr_o, wbm_dat_o, wbm_dat_i, wbm_sel_o, wbm_tga_o, wbm_we_o,
|
wbm_stb_o, wbm_cyc_o, wbm_ack_i,
|
wbm_stb_o, wbm_cyc_o, wbm_ack_i,
|
dma_chan_o, dma_tc_o,
|
dma_chan_o, dma_tc_o,
|
lframe_i, lad_i, lad_o, lad_oe
|
lframe_i, lad_i, lad_o, lad_oe
|
);
|
);
|
|
|
// Wishbone Master Interface
|
// Wishbone Master Interface
|
input clk_i;
|
input clk_i;
|
input nrst_i;
|
input nrst_i;
|
output reg [31:0] wbm_adr_o;
|
output reg [31:0] wbm_adr_o;
|
output reg [31:0] wbm_dat_o;
|
output reg [31:0] wbm_dat_o;
|
input [31:0] wbm_dat_i;
|
input [31:0] wbm_dat_i;
|
output reg [3:0] wbm_sel_o;
|
output reg [3:0] wbm_sel_o;
|
output reg [1:0] wbm_tga_o;
|
output reg [1:0] wbm_tga_o;
|
output reg wbm_we_o;
|
output reg wbm_we_o;
|
output reg wbm_stb_o;
|
output reg wbm_stb_o;
|
output reg wbm_cyc_o;
|
output reg wbm_cyc_o;
|
input wbm_ack_i;
|
input wbm_ack_i;
|
|
|
// LPC Slave Interface
|
// LPC Slave Interface
|
input lframe_i; // LPC Frame input (active high)
|
input lframe_i; // LPC Frame input (active high)
|
output reg lad_oe; // LPC AD Output Enable
|
output reg lad_oe; // LPC AD Output Enable
|
input [3:0] lad_i; // LPC AD Input Bus
|
input [3:0] lad_i; // LPC AD Input Bus
|
output reg [3:0] lad_o; // LPC AD Output Bus
|
output reg [3:0] lad_o; // LPC AD Output Bus
|
|
|
// DMA-Specific sideband signals
|
// DMA-Specific sideband signals
|
output [2:0] dma_chan_o; // DMA Channel
|
output [2:0] dma_chan_o; // DMA Channel
|
output dma_tc_o; // DMA Terminal Count
|
output dma_tc_o; // DMA Terminal Count
|
|
|
reg [12:0] state; // Current state
|
reg [12:0] state; // Current state
|
reg [2:0] adr_cnt; // Address nibbe counter
|
reg [2:0] adr_cnt; // Address nibble counter
|
reg [3:0] dat_cnt; // Data nibble counter
|
reg [3:0] dat_cnt; // Data nibble counter
|
wire [2:0] byte_cnt = dat_cnt[3:1]; // Byte counter
|
wire [2:0] byte_cnt = dat_cnt[3:1]; // Byte counter
|
wire nibble_cnt = dat_cnt[0]; // Nibble counter
|
wire nibble_cnt = dat_cnt[0]; // Nibble counter
|
|
|
reg [31:0] lpc_dat_i; // Temporary storage for input data.
|
reg [31:0] lpc_dat_i; // Temporary storage for input data.
|
reg [3:0] start_type; // Type of LPC start cycle
|
reg [3:0] start_type; // Type of LPC start cycle
|
reg mem_xfr; // LPC Memory Transfer (not I/O)
|
reg mem_xfr; // LPC Memory Transfer (not I/O)
|
reg dma_xfr; // LPC DMA Transfer
|
reg dma_xfr; // LPC DMA Transfer
|
reg fw_xfr; // LPC Firmware memory read/write
|
reg fw_xfr; // LPC Firmware memory read/write
|
reg [2:0] xfr_len; // Number of nibbls for transfer
|
reg [2:0] xfr_len; // Number of nibbls for transfer
|
reg dma_tc; // DMA Terminal Count
|
reg dma_tc; // DMA Terminal Count
|
reg [2:0] dma_chan; // DMA Channel
|
reg [2:0] dma_chan; // DMA Channel
|
|
|
assign dma_chan_o = dma_chan;
|
assign dma_chan_o = dma_chan;
|
assign dma_tc_o = dma_tc;
|
assign dma_tc_o = dma_tc;
|
|
|
always @(posedge clk_i or negedge nrst_i)
|
always @(posedge clk_i or negedge nrst_i)
|
if(~nrst_i)
|
if(~nrst_i)
|
begin
|
begin
|
state <= `LPC_ST_IDLE;
|
state <= `LPC_ST_IDLE;
|
wbm_adr_o <= 16'h0000;
|
wbm_adr_o <= 16'h0000;
|
wbm_dat_o <= 32'h00000000;
|
wbm_dat_o <= 32'h00000000;
|
wbm_sel_o <= 4'b0000;
|
wbm_sel_o <= 4'b0000;
|
wbm_tga_o <= `WB_TGA_MEM;
|
wbm_tga_o <= `WB_TGA_MEM;
|
wbm_we_o <= 1'b0;
|
wbm_we_o <= 1'b0;
|
wbm_stb_o <= 1'b0;
|
wbm_stb_o <= 1'b0;
|
wbm_cyc_o <= 1'b0;
|
wbm_cyc_o <= 1'b0;
|
lad_oe <= 1'b0;
|
lad_oe <= 1'b0;
|
lad_o <= 8'hFF;
|
lad_o <= 8'hFF;
|
lpc_dat_i <= 32'h00;
|
lpc_dat_i <= 32'h00;
|
start_type <= 4'b0000;
|
start_type <= 4'b0000;
|
wbm_tga_o <= `WB_TGA_MEM;
|
wbm_tga_o <= `WB_TGA_MEM;
|
mem_xfr <= 1'b0;
|
mem_xfr <= 1'b0;
|
dma_xfr <= 1'b0;
|
dma_xfr <= 1'b0;
|
fw_xfr <= 1'b0;
|
fw_xfr <= 1'b0;
|
xfr_len <= 3'b000;
|
xfr_len <= 3'b000;
|
dma_tc <= 1'b0;
|
dma_tc <= 1'b0;
|
dma_chan <= 3'b000;
|
dma_chan <= 3'b000;
|
end
|
end
|
else begin
|
else begin
|
case(state)
|
case(state)
|
`LPC_ST_IDLE:
|
`LPC_ST_IDLE:
|
begin
|
begin
|
dat_cnt <= 4'h0;
|
dat_cnt <= 4'h0;
|
if(lframe_i)
|
if(lframe_i)
|
begin
|
begin
|
start_type <= lad_i;
|
start_type <= lad_i;
|
wbm_sel_o <= 4'b0000;
|
wbm_sel_o <= 4'b0000;
|
wbm_stb_o <= 1'b0;
|
wbm_stb_o <= 1'b0;
|
wbm_cyc_o <= 1'b0;
|
wbm_cyc_o <= 1'b0;
|
lad_oe <= 1'b0;
|
lad_oe <= 1'b0;
|
xfr_len <= 3'b001;
|
xfr_len <= 3'b001;
|
|
|
if(lad_i == `LPC_START) begin
|
if(lad_i == `LPC_START) begin
|
state <= `LPC_ST_CYCTYP;
|
state <= `LPC_ST_CYCTYP;
|
wbm_we_o <= 1'b0;
|
wbm_we_o <= 1'b0;
|
fw_xfr <= 1'b0;
|
fw_xfr <= 1'b0;
|
end
|
end
|
else if (lad_i == `LPC_FW_READ) begin
|
else if (lad_i == `LPC_FW_READ) begin
|
state <= `LPC_ST_ADDR;
|
state <= `LPC_ST_ADDR;
|
wbm_we_o <= 1'b0;
|
wbm_we_o <= 1'b0;
|
adr_cnt <= 3'b000;
|
adr_cnt <= 3'b000;
|
fw_xfr <= 1'b1;
|
fw_xfr <= 1'b1;
|
wbm_tga_o <= `WB_TGA_FW;
|
wbm_tga_o <= `WB_TGA_FW;
|
end
|
end
|
else if (lad_i == `LPC_FW_WRITE) begin
|
else if (lad_i == `LPC_FW_WRITE) begin
|
state <= `LPC_ST_ADDR;
|
state <= `LPC_ST_ADDR;
|
wbm_we_o <= 1'b1;
|
wbm_we_o <= 1'b1;
|
adr_cnt <= 3'b000;
|
adr_cnt <= 3'b000;
|
fw_xfr <= 1'b1;
|
fw_xfr <= 1'b1;
|
wbm_tga_o <= `WB_TGA_FW;
|
wbm_tga_o <= `WB_TGA_FW;
|
end
|
end
|
else
|
else
|
state <= `LPC_ST_IDLE;
|
state <= `LPC_ST_IDLE;
|
end
|
end
|
else
|
else
|
state <= `LPC_ST_IDLE;
|
state <= `LPC_ST_IDLE;
|
end
|
end
|
`LPC_ST_CYCTYP:
|
`LPC_ST_CYCTYP:
|
begin
|
begin
|
wbm_we_o <= (lad_i[3] ? ~lad_i[1] : lad_i[1]); // Invert we_o if we are doing DMA.
|
wbm_we_o <= (lad_i[3] ? ~lad_i[1] : lad_i[1]); // Invert we_o if we are doing DMA.
|
mem_xfr <= lad_i[2];
|
mem_xfr <= lad_i[2];
|
dma_xfr <= lad_i[3];
|
dma_xfr <= lad_i[3];
|
adr_cnt <= (lad_i[2] ? 3'b000 : 3'b100);
|
adr_cnt <= (lad_i[2] ? 3'b000 : 3'b100);
|
if(lad_i[3]) // dma_xfr)
|
if(lad_i[3]) // dma_xfr)
|
wbm_tga_o <= `WB_TGA_DMA;
|
wbm_tga_o <= `WB_TGA_DMA;
|
else if(lad_i[2]) //mem_xfr)
|
else if(lad_i[2]) //mem_xfr)
|
wbm_tga_o <= `WB_TGA_MEM;
|
wbm_tga_o <= `WB_TGA_MEM;
|
else
|
else
|
wbm_tga_o <= `WB_TGA_IO;
|
wbm_tga_o <= `WB_TGA_IO;
|
|
|
if(lad_i[3]) //dma_xfr)
|
if(lad_i[3]) //dma_xfr)
|
begin
|
begin
|
state <= `LPC_ST_CHAN;
|
state <= `LPC_ST_CHAN;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= `LPC_ST_ADDR;
|
state <= `LPC_ST_ADDR;
|
end
|
end
|
end
|
end
|
`LPC_ST_ADDR:
|
`LPC_ST_ADDR:
|
begin
|
begin
|
case(adr_cnt)
|
case(adr_cnt)
|
3'h0:
|
3'h0:
|
wbm_adr_o[31:28] <= lad_i;
|
wbm_adr_o[31:28] <= lad_i;
|
3'h1:
|
3'h1:
|
wbm_adr_o[27:24] <= lad_i;
|
wbm_adr_o[27:24] <= lad_i;
|
3'h2:
|
3'h2:
|
wbm_adr_o[23:20] <= lad_i;
|
wbm_adr_o[23:20] <= lad_i;
|
3'h3:
|
3'h3:
|
wbm_adr_o[19:16] <= lad_i;
|
wbm_adr_o[19:16] <= lad_i;
|
3'h4:
|
3'h4:
|
wbm_adr_o[15:12] <= lad_i;
|
wbm_adr_o[15:12] <= lad_i;
|
3'h5:
|
3'h5:
|
wbm_adr_o[11:8] <= lad_i;
|
wbm_adr_o[11:8] <= lad_i;
|
3'h6:
|
3'h6:
|
wbm_adr_o[7:4] <= lad_i;
|
wbm_adr_o[7:4] <= lad_i;
|
3'h7:
|
3'h7:
|
wbm_adr_o[3:0] <= lad_i;
|
wbm_adr_o[3:0] <= lad_i;
|
endcase
|
endcase
|
|
|
adr_cnt <= adr_cnt + 1;
|
adr_cnt <= adr_cnt + 1;
|
|
|
if(adr_cnt == 3'h7) // Last address nibble.
|
if(adr_cnt == 3'h7) // Last address nibble.
|
begin
|
begin
|
if(~fw_xfr)
|
if(~fw_xfr)
|
if(wbm_we_o)
|
if(wbm_we_o)
|
state <= `LPC_ST_H_DATA;
|
state <= `LPC_ST_H_DATA;
|
else
|
else
|
state <= `LPC_ST_H_TAR1;
|
state <= `LPC_ST_H_TAR1;
|
else // For firmware read/write, we need to read the MSIZE nibble
|
else // For firmware read/write, we need to read the MSIZE nibble
|
state <= `LPC_ST_SIZE;
|
state <= `LPC_ST_SIZE;
|
end
|
end
|
else
|
else
|
state <= `LPC_ST_ADDR;
|
state <= `LPC_ST_ADDR;
|
end
|
end
|
`LPC_ST_CHAN:
|
`LPC_ST_CHAN:
|
begin
|
begin
|
wbm_adr_o <= 32'h00000000; // Address lines not used for DMA.
|
wbm_adr_o <= 32'h00000000; // Address lines not used for DMA.
|
dma_tc <= lad_i[3];
|
dma_tc <= lad_i[3];
|
dma_chan <= lad_i[2:0];
|
dma_chan <= lad_i[2:0];
|
state <= `LPC_ST_SIZE;
|
state <= `LPC_ST_SIZE;
|
end
|
end
|
`LPC_ST_SIZE:
|
`LPC_ST_SIZE:
|
begin
|
begin
|
case(lad_i)
|
case(lad_i)
|
4'h0:
|
4'h0:
|
begin
|
begin
|
xfr_len <= 3'b001;
|
xfr_len <= 3'b001;
|
wbm_sel_o <= `WB_SEL_BYTE;
|
wbm_sel_o <= `WB_SEL_BYTE;
|
end
|
end
|
4'h1:
|
4'h1:
|
begin
|
begin
|
xfr_len <= 3'b010;
|
xfr_len <= 3'b010;
|
wbm_sel_o <= `WB_SEL_SHORT;
|
wbm_sel_o <= `WB_SEL_SHORT;
|
end
|
end
|
4'h2: // Firmware transfer uses '2' for 4-byte transfer.
|
4'h2: // Firmware transfer uses '2' for 4-byte transfer.
|
begin
|
begin
|
xfr_len <= 3'b100;
|
xfr_len <= 3'b100;
|
wbm_sel_o <= `WB_SEL_WORD;
|
wbm_sel_o <= `WB_SEL_WORD;
|
end
|
end
|
4'h3: // DMA uses '3' for 4-byte transfer.
|
4'h3: // DMA uses '3' for 4-byte transfer.
|
begin
|
begin
|
xfr_len <= 3'b100;
|
xfr_len <= 3'b100;
|
wbm_sel_o <= `WB_SEL_WORD;
|
wbm_sel_o <= `WB_SEL_WORD;
|
end
|
end
|
default:
|
default:
|
begin
|
begin
|
xfr_len <= 3'b001;
|
xfr_len <= 3'b001;
|
wbm_sel_o <= 4'b0000;
|
wbm_sel_o <= 4'b0000;
|
end
|
end
|
endcase
|
endcase
|
if(wbm_we_o)
|
if(wbm_we_o)
|
state <= `LPC_ST_H_DATA;
|
state <= `LPC_ST_H_DATA;
|
else
|
else
|
state <= `LPC_ST_H_TAR1;
|
state <= `LPC_ST_H_TAR1;
|
end
|
end
|
`LPC_ST_H_DATA:
|
`LPC_ST_H_DATA:
|
begin
|
begin
|
case(dat_cnt)
|
case(dat_cnt)
|
4'h0:
|
4'h0:
|
wbm_dat_o[3:0] <= lad_i;
|
wbm_dat_o[3:0] <= lad_i;
|
4'h1:
|
4'h1:
|
wbm_dat_o[7:4] <= lad_i;
|
wbm_dat_o[7:4] <= lad_i;
|
4'h2:
|
4'h2:
|
wbm_dat_o[11:8] <= lad_i;
|
wbm_dat_o[11:8] <= lad_i;
|
4'h3:
|
4'h3:
|
wbm_dat_o[15:12] <= lad_i;
|
wbm_dat_o[15:12] <= lad_i;
|
4'h4:
|
4'h4:
|
wbm_dat_o[19:16] <= lad_i;
|
wbm_dat_o[19:16] <= lad_i;
|
4'h5:
|
4'h5:
|
wbm_dat_o[23:20] <= lad_i;
|
wbm_dat_o[23:20] <= lad_i;
|
4'h6:
|
4'h6:
|
wbm_dat_o[27:24] <= lad_i;
|
wbm_dat_o[27:24] <= lad_i;
|
4'h7:
|
4'h7:
|
wbm_dat_o[31:28] <= lad_i;
|
wbm_dat_o[31:28] <= lad_i;
|
endcase
|
endcase
|
|
|
dat_cnt <= dat_cnt + 1;
|
dat_cnt <= dat_cnt + 1;
|
|
|
if(nibble_cnt == 1'b1) // end of byte
|
if(nibble_cnt == 1'b1) // end of byte
|
begin
|
begin
|
state <= `LPC_ST_H_TAR1;
|
state <= `LPC_ST_H_TAR1;
|
end
|
end
|
else
|
else
|
state <= `LPC_ST_H_DATA;
|
state <= `LPC_ST_H_DATA;
|
|
|
end
|
end
|
|
|
`LPC_ST_H_TAR1:
|
`LPC_ST_H_TAR1:
|
begin
|
begin
|
if(((byte_cnt == xfr_len) & wbm_we_o) | ((byte_cnt == 0) & ~wbm_we_o))
|
if(((byte_cnt == xfr_len) & wbm_we_o) | ((byte_cnt == 0) & ~wbm_we_o))
|
begin
|
begin
|
wbm_stb_o <= 1'b1;
|
wbm_stb_o <= 1'b1;
|
wbm_cyc_o <= 1'b1;
|
wbm_cyc_o <= 1'b1;
|
end
|
end
|
state <= `LPC_ST_H_TAR2;
|
state <= `LPC_ST_H_TAR2;
|
end
|
end
|
`LPC_ST_H_TAR2:
|
`LPC_ST_H_TAR2:
|
begin
|
begin
|
state <= `LPC_ST_SYNC;
|
state <= `LPC_ST_SYNC;
|
lad_oe <= 1'b1; // start driving LAD
|
lad_oe <= 1'b1; // start driving LAD
|
lad_o <= `LPC_SYNC_SWAIT;
|
lad_o <= `LPC_SYNC_SWAIT;
|
end
|
end
|
`LPC_ST_SYNC:
|
`LPC_ST_SYNC:
|
begin
|
begin
|
lad_oe <= 1'b1; // start driving LAD
|
lad_oe <= 1'b1; // start driving LAD
|
if(((byte_cnt == xfr_len) & wbm_we_o) | ((byte_cnt == 0) & ~wbm_we_o)) begin
|
if(((byte_cnt == xfr_len) & wbm_we_o) | ((byte_cnt == 0) & ~wbm_we_o)) begin
|
if(wbm_ack_i)
|
if(wbm_ack_i)
|
begin
|
begin
|
lad_o <= `LPC_SYNC_READY; // Ready
|
lad_o <= `LPC_SYNC_READY; // Ready
|
wbm_stb_o <= 1'b0; // End Wishbone cycle.
|
wbm_stb_o <= 1'b0; // End Wishbone cycle.
|
wbm_cyc_o <= 1'b0;
|
wbm_cyc_o <= 1'b0;
|
if(wbm_we_o)
|
if(wbm_we_o)
|
state <= `LPC_ST_P_TAR1;
|
state <= `LPC_ST_P_TAR1;
|
else
|
else
|
begin
|
begin
|
lpc_dat_i <= wbm_dat_i[31:0];
|
lpc_dat_i <= wbm_dat_i[31:0];
|
state <= `LPC_ST_P_DATA;
|
state <= `LPC_ST_P_DATA;
|
end
|
end
|
end
|
end
|
else
|
else
|
begin
|
begin
|
state <= `LPC_ST_SYNC;
|
state <= `LPC_ST_SYNC;
|
lad_o <= `LPC_SYNC_SWAIT;
|
lad_o <= `LPC_SYNC_SWAIT;
|
end
|
end
|
end
|
end
|
else begin // Multi-byte transfer, just ack right away.
|
else begin // Multi-byte transfer, just ack right away.
|
lad_o <= `LPC_SYNC_READY; // Ready
|
lad_o <= `LPC_SYNC_READY; // Ready
|
if(wbm_we_o)
|
if(wbm_we_o)
|
state <= `LPC_ST_P_TAR1;
|
state <= `LPC_ST_P_TAR1;
|
else
|
else
|
state <= `LPC_ST_P_DATA;
|
state <= `LPC_ST_P_DATA;
|
end
|
end
|
end
|
end
|
|
|
`LPC_ST_P_DATA:
|
`LPC_ST_P_DATA:
|
begin
|
begin
|
case(dat_cnt)
|
case(dat_cnt)
|
4'h0:
|
4'h0:
|
lad_o <= lpc_dat_i[3:0];
|
lad_o <= lpc_dat_i[3:0];
|
4'h1:
|
4'h1:
|
lad_o <= lpc_dat_i[7:4];
|
lad_o <= lpc_dat_i[7:4];
|
4'h2:
|
4'h2:
|
lad_o <= lpc_dat_i[11:8];
|
lad_o <= lpc_dat_i[11:8];
|
4'h3:
|
4'h3:
|
lad_o <= lpc_dat_i[15:12];
|
lad_o <= lpc_dat_i[15:12];
|
4'h4:
|
4'h4:
|
lad_o <= lpc_dat_i[19:16];
|
lad_o <= lpc_dat_i[19:16];
|
4'h5:
|
4'h5:
|
lad_o <= lpc_dat_i[23:20];
|
lad_o <= lpc_dat_i[23:20];
|
4'h6:
|
4'h6:
|
lad_o <= lpc_dat_i[27:24];
|
lad_o <= lpc_dat_i[27:24];
|
4'h7:
|
4'h7:
|
lad_o <= lpc_dat_i[31:28];
|
lad_o <= lpc_dat_i[31:28];
|
endcase
|
endcase
|
|
|
dat_cnt <= dat_cnt + 1;
|
dat_cnt <= dat_cnt + 1;
|
|
|
// if(nibble_cnt == 1'b1)
|
|
// state <= `LPC_ST_P_TAR1;
|
|
|
|
if(nibble_cnt == 1'b1) // Byte transfer complete
|
if(nibble_cnt == 1'b1) // Byte transfer complete
|
if (byte_cnt == xfr_len-1) // Byte transfer complete
|
if (byte_cnt == xfr_len-1) // Byte transfer complete
|
state <= `LPC_ST_P_TAR1;
|
state <= `LPC_ST_P_TAR1;
|
else
|
else
|
state <= `LPC_ST_SYNC;
|
state <= `LPC_ST_SYNC;
|
else
|
else
|
state <= `LPC_ST_P_DATA;
|
state <= `LPC_ST_P_DATA;
|
|
|
lad_oe <= 1'b1;
|
lad_oe <= 1'b1;
|
end
|
end
|
`LPC_ST_P_TAR1:
|
`LPC_ST_P_TAR1:
|
begin
|
begin
|
lad_oe <= 1'b1;
|
lad_oe <= 1'b1;
|
lad_o <= 4'hF;
|
lad_o <= 4'hF;
|
state <= `LPC_ST_P_TAR2;
|
state <= `LPC_ST_P_TAR2;
|
end
|
end
|
`LPC_ST_P_TAR2:
|
`LPC_ST_P_TAR2:
|
begin
|
begin
|
lad_oe <= 1'b0; // float LAD
|
lad_oe <= 1'b0; // float LAD
|
if(byte_cnt == xfr_len) begin
|
if(byte_cnt == xfr_len) begin
|
state <= `LPC_ST_IDLE;
|
state <= `LPC_ST_IDLE;
|
end
|
end
|
else begin
|
else begin
|
if(wbm_we_o) begin // DMA READ (Host to Peripheral)
|
if(wbm_we_o) begin // DMA READ (Host to Peripheral)
|
state <= `LPC_ST_P_WAIT1;
|
state <= `LPC_ST_P_WAIT1;
|
end
|
end
|
else begin // unhandled READ case
|
else begin // unhandled READ case
|
state <= `LPC_ST_IDLE;
|
state <= `LPC_ST_IDLE;
|
end
|
end
|
end
|
end
|
|
|
end
|
end
|
`LPC_ST_P_WAIT1:
|
`LPC_ST_P_WAIT1:
|
state <= `LPC_ST_H_DATA;
|
state <= `LPC_ST_H_DATA;
|
endcase
|
endcase
|
end
|
end
|
|
|
endmodule
|
endmodule
|
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|