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 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/trunk/rtl/verilog/wb_lpc_periph.v
0,0 → 1,407
////////////////////////////////////////////////////////////////////// |
//// //// |
//// $Id: wb_lpc_periph.v,v 1.1 2008-03-02 20:46:40 hharte Exp $ |
//// wb_lpc_periph.v - LPC Peripheral to Wishbone Master Bridge //// |
//// //// |
//// This file is part of the Wishbone LPC Bridge project //// |
//// http://www.opencores.org/projects/wb_lpc/ //// |
//// //// |
//// Author: //// |
//// - Howard M. Harte (hharte@opencores.org) //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2008 Howard M. Harte //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
|
`timescale 1 ns / 1 ns |
|
`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 |
// |
|
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, |
dma_chan_o, dma_tc_o, |
lframe_i, lad_i, lad_o, lad_oe |
); |
|
// Wishbone Master Interface |
input clk_i; |
input nrst_i; |
output reg [31:0] wbm_adr_o; |
output reg [31:0] wbm_dat_o; |
input [31:0] wbm_dat_i; |
output reg [3:0] wbm_sel_o; |
output reg [1:0] wbm_tga_o; |
output reg wbm_we_o; |
output reg wbm_stb_o; |
output reg wbm_cyc_o; |
input wbm_ack_i; |
|
// LPC Slave Interface |
input lframe_i; // LPC Frame input (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 |
output [2:0] dma_chan_o; // DMA Channel |
output dma_tc_o; // 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 |
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 data. |
reg [3:0] start_type; // Type of LPC start cycle |
reg mem_xfr; // LPC Memory Transfer (not I/O) |
reg dma_xfr; // LPC DMA Transfer |
reg fw_xfr; // LPC Firmware memory read/write |
reg [2:0] xfr_len; // Number of nibbls for transfer |
reg dma_tc; // DMA Terminal Count |
reg [2:0] dma_chan; // DMA Channel |
|
assign dma_chan_o = dma_chan; |
assign dma_tc_o = dma_tc; |
|
always @(posedge clk_i or negedge nrst_i) |
if(~nrst_i) |
begin |
state <= `LPC_ST_IDLE; |
wbm_adr_o <= 16'h0000; |
wbm_dat_o <= 32'h00000000; |
wbm_sel_o <= 4'b0000; |
wbm_tga_o <= `WB_TGA_MEM; |
wbm_we_o <= 1'b0; |
wbm_stb_o <= 1'b0; |
wbm_cyc_o <= 1'b0; |
lad_oe <= 1'b0; |
lad_o <= 8'hFF; |
lpc_dat_i <= 32'h00; |
start_type <= 4'b0000; |
wbm_tga_o <= `WB_TGA_MEM; |
mem_xfr <= 1'b0; |
dma_xfr <= 1'b0; |
fw_xfr <= 1'b0; |
xfr_len <= 3'b000; |
dma_tc <= 1'b0; |
dma_chan <= 3'b000; |
end |
else begin |
case(state) |
`LPC_ST_IDLE: |
begin |
dat_cnt <= 4'h0; |
if(lframe_i) |
begin |
start_type <= lad_i; |
wbm_sel_o <= 4'b0000; |
wbm_stb_o <= 1'b0; |
wbm_cyc_o <= 1'b0; |
lad_oe <= 1'b0; |
xfr_len <= 3'b001; |
|
if(lad_i == `LPC_START) begin |
state <= `LPC_ST_CYCTYP; |
wbm_we_o <= 1'b0; |
fw_xfr <= 1'b0; |
end |
else if (lad_i == `LPC_FW_READ) begin |
state <= `LPC_ST_ADDR; |
wbm_we_o <= 1'b0; |
adr_cnt <= 3'b000; |
fw_xfr <= 1'b1; |
wbm_tga_o <= `WB_TGA_FW; |
end |
else if (lad_i == `LPC_FW_WRITE) begin |
state <= `LPC_ST_ADDR; |
wbm_we_o <= 1'b1; |
adr_cnt <= 3'b000; |
fw_xfr <= 1'b1; |
wbm_tga_o <= `WB_TGA_FW; |
end |
else |
state <= `LPC_ST_IDLE; |
end |
else |
state <= `LPC_ST_IDLE; |
end |
`LPC_ST_CYCTYP: |
begin |
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]; |
dma_xfr <= lad_i[3]; |
adr_cnt <= (lad_i[2] ? 3'b000 : 3'b100); |
if(lad_i[3]) // dma_xfr) |
wbm_tga_o <= `WB_TGA_DMA; |
else if(lad_i[2]) //mem_xfr) |
wbm_tga_o <= `WB_TGA_MEM; |
else |
wbm_tga_o <= `WB_TGA_IO; |
|
if(lad_i[3]) //dma_xfr) |
begin |
state <= `LPC_ST_CHAN; |
end |
else |
begin |
state <= `LPC_ST_ADDR; |
end |
end |
`LPC_ST_ADDR: |
begin |
case(adr_cnt) |
3'h0: |
wbm_adr_o[31:28] <= lad_i; |
3'h1: |
wbm_adr_o[27:24] <= lad_i; |
3'h2: |
wbm_adr_o[23:20] <= lad_i; |
3'h3: |
wbm_adr_o[19:16] <= lad_i; |
3'h4: |
wbm_adr_o[15:12] <= lad_i; |
3'h5: |
wbm_adr_o[11:8] <= lad_i; |
3'h6: |
wbm_adr_o[7:4] <= lad_i; |
3'h7: |
wbm_adr_o[3:0] <= lad_i; |
endcase |
|
adr_cnt <= adr_cnt + 1; |
|
if(adr_cnt == 3'h7) // Last address nibble. |
begin |
if(~fw_xfr) |
if(wbm_we_o) |
state <= `LPC_ST_H_DATA; |
else |
state <= `LPC_ST_H_TAR1; |
else // For firmware read/write, we need to read the MSIZE nibble |
state <= `LPC_ST_SIZE; |
end |
else |
state <= `LPC_ST_ADDR; |
end |
`LPC_ST_CHAN: |
begin |
wbm_adr_o <= 32'h00000000; // Address lines not used for DMA. |
dma_tc <= lad_i[3]; |
dma_chan <= lad_i[2:0]; |
state <= `LPC_ST_SIZE; |
end |
`LPC_ST_SIZE: |
begin |
case(lad_i) |
4'h0: |
begin |
xfr_len <= 3'b001; |
wbm_sel_o <= `WB_SEL_BYTE; |
end |
4'h1: |
begin |
xfr_len <= 3'b010; |
wbm_sel_o <= `WB_SEL_SHORT; |
end |
4'h2: // Firmware transfer uses '2' for 4-byte transfer. |
begin |
xfr_len <= 3'b100; |
wbm_sel_o <= `WB_SEL_WORD; |
end |
4'h3: // DMA uses '3' for 4-byte transfer. |
begin |
xfr_len <= 3'b100; |
wbm_sel_o <= `WB_SEL_WORD; |
end |
default: |
begin |
xfr_len <= 3'b001; |
wbm_sel_o <= 4'b0000; |
end |
endcase |
if(wbm_we_o) |
state <= `LPC_ST_H_DATA; |
else |
state <= `LPC_ST_H_TAR1; |
end |
`LPC_ST_H_DATA: |
begin |
case(dat_cnt) |
4'h0: |
wbm_dat_o[3:0] <= lad_i; |
4'h1: |
wbm_dat_o[7:4] <= lad_i; |
4'h2: |
wbm_dat_o[11:8] <= lad_i; |
4'h3: |
wbm_dat_o[15:12] <= lad_i; |
4'h4: |
wbm_dat_o[19:16] <= lad_i; |
4'h5: |
wbm_dat_o[23:20] <= lad_i; |
4'h6: |
wbm_dat_o[27:24] <= lad_i; |
4'h7: |
wbm_dat_o[31:28] <= lad_i; |
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 |
if(((byte_cnt == xfr_len) & wbm_we_o) | ((byte_cnt == 0) & ~wbm_we_o)) |
begin |
wbm_stb_o <= 1'b1; |
wbm_cyc_o <= 1'b1; |
end |
state <= `LPC_ST_H_TAR2; |
end |
`LPC_ST_H_TAR2: |
begin |
state <= `LPC_ST_SYNC; |
lad_oe <= 1'b1; // start driving LAD |
lad_o <= `LPC_SYNC_SWAIT; |
end |
`LPC_ST_SYNC: |
begin |
lad_oe <= 1'b1; // start driving LAD |
if(((byte_cnt == xfr_len) & wbm_we_o) | ((byte_cnt == 0) & ~wbm_we_o)) begin |
if(wbm_ack_i) |
begin |
lad_o <= `LPC_SYNC_READY; // Ready |
wbm_stb_o <= 1'b0; // End Wishbone cycle. |
wbm_cyc_o <= 1'b0; |
if(wbm_we_o) |
state <= `LPC_ST_P_TAR1; |
else |
begin |
lpc_dat_i <= wbm_dat_i[31:0]; |
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. |
lad_o <= `LPC_SYNC_READY; // Ready |
if(wbm_we_o) |
state <= `LPC_ST_P_TAR1; |
else |
state <= `LPC_ST_P_DATA; |
end |
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) |
// state <= `LPC_ST_P_TAR1; |
|
if(nibble_cnt == 1'b1) // Byte transfer complete |
if (byte_cnt == xfr_len-1) // Byte transfer complete |
state <= `LPC_ST_P_TAR1; |
else |
state <= `LPC_ST_SYNC; |
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(wbm_we_o) 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 |
|
endmodule |
|
|
trunk/rtl/verilog/wb_lpc_periph.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/rtl/verilog/wb_dreq_host.v
===================================================================
--- trunk/rtl/verilog/wb_dreq_host.v (nonexistent)
+++ trunk/rtl/verilog/wb_dreq_host.v (revision 3)
@@ -0,0 +1,103 @@
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// $Id: wb_dreq_host.v,v 1.1 2008-03-02 20:46:40 hharte Exp $
+//// wb_dreq_host.v - Wishbone DMA Controller for LPC Host ////
+//// ////
+//// This file is part of the Wishbone LPC Bridge project ////
+//// http://www.opencores.org/projects/wb_lpc/ ////
+//// ////
+//// Author: ////
+//// - Howard M. Harte (hharte@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Howard M. Harte ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ns
+
+`include "../../rtl/verilog/wb_lpc_defines.v"
+
+module wb_dreq_host(clk_i, nrst_i,
+ dma_chan_o, dma_req_o,
+ ldrq_i
+);
+ // Wishbone Slave Interface
+ input clk_i;
+ input nrst_i; // Active low reset.
+
+ // Private DMA Interface
+ output reg [2:0] dma_chan_o;
+ output reg dma_req_o;
+
+ // LPC Bus DMA Request Input
+ input ldrq_i;
+
+ reg [1:0] adr_cnt;
+ reg [3:0] state;
+
+ always @(posedge clk_i or negedge nrst_i)
+ if(~nrst_i)
+ begin
+ state <= `LDRQ_ST_IDLE;
+ dma_chan_o <= 3'h0;
+ dma_req_o <= 3'h0;
+ adr_cnt <= 2'b00;
+ end
+ else begin
+ case(state)
+ `LDRQ_ST_IDLE:
+ begin
+ dma_req_o <= 1'b0;
+ if(~ldrq_i) begin
+ state <= `LDRQ_ST_ADDR;
+ adr_cnt <= 2'h2;
+ end
+ end
+ `LDRQ_ST_ADDR:
+ begin
+ dma_chan_o[adr_cnt] <= ldrq_i;
+ adr_cnt <= adr_cnt - 1;
+
+ if(adr_cnt == 2'h0)
+ state <= `LDRQ_ST_ACT;
+ end
+ `LDRQ_ST_ACT:
+ begin
+ dma_req_o <= ldrq_i;
+ state <= `LDRQ_ST_DONE;
+ end
+ `LDRQ_ST_DONE:
+ begin
+ dma_req_o <= 1'b0;
+ state <= `LDRQ_ST_IDLE;
+ end
+ endcase
+ end
+
+endmodule
+
+
\ No newline at end of file
trunk/rtl/verilog/wb_dreq_host.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/rtl/verilog/wb_lpc_defines.v
===================================================================
--- trunk/rtl/verilog/wb_lpc_defines.v (nonexistent)
+++ trunk/rtl/verilog/wb_lpc_defines.v (revision 3)
@@ -0,0 +1,81 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// wb_lpc_defines.v ////
+//// ////
+//// This file is part of the Wishbone LPC Bridge project ////
+//// http://www.opencores.org/projects/wb_lpc/ ////
+//// ////
+//// Author: ////
+//// - Howard M. Harte (hharte@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Howard M. Harte ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+// 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_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 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
+
+// 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
trunk/rtl/verilog/wb_lpc_defines.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/rtl/verilog/wb_lpc_host.v
===================================================================
--- trunk/rtl/verilog/wb_lpc_host.v (nonexistent)
+++ trunk/rtl/verilog/wb_lpc_host.v (revision 3)
@@ -0,0 +1,362 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// $Id: wb_lpc_host.v,v 1.1 2008-03-02 20:46:40 hharte Exp $
+//// wb_lpc_host.v - Wishbone Slave to LPC Host Bridge ////
+//// ////
+//// This file is part of the Wishbone LPC Bridge project ////
+//// http://www.opencores.org/projects/wb_lpc/ ////
+//// ////
+//// Author: ////
+//// - Howard M. Harte (hharte@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Howard M. Harte ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ns
+
+`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
+//
+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
+);
+ // 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
+
+ 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
+
+ // 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;
+
+ 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
+
+ `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
+
+endmodule
+
+
\ No newline at end of file
trunk/rtl/verilog/wb_lpc_host.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/rtl/verilog/wb_regfile.v
===================================================================
--- trunk/rtl/verilog/wb_regfile.v (nonexistent)
+++ trunk/rtl/verilog/wb_regfile.v (revision 3)
@@ -0,0 +1,158 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// $Id: wb_regfile.v,v 1.1 2008-03-02 20:46:40 hharte Exp $
+//// wb_regfile.v - Small Wishbone register file for testing ////
+//// ////
+//// This file is part of the Wishbone LPC Bridge project ////
+//// http://www.opencores.org/projects/wb_lpc/ ////
+//// ////
+//// Author: ////
+//// - Howard M. Harte (hharte@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Howard M. Harte ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module wb_regfile (clk_i, nrst_i, wb_adr_i, wb_dat_o, wb_dat_i, wb_sel_i, wb_we_i,
+ wb_stb_i, wb_cyc_i, wb_ack_o, datareg0, datareg1);
+
+ input clk_i;
+ input nrst_i;
+ input [2:0] wb_adr_i;
+ output reg [31:0] wb_dat_o;
+ input [31:0] wb_dat_i;
+ input [3:0] wb_sel_i;
+ input wb_we_i;
+ input wb_stb_i;
+ input wb_cyc_i;
+ output reg wb_ack_o;
+ output [31:0] datareg0;
+ output [31:0] datareg1;
+
+ //
+ // generate wishbone register bank writes
+ wire wb_acc = wb_cyc_i & wb_stb_i; // WISHBONE access
+ wire wb_wr = wb_acc & wb_we_i; // WISHBONE write access
+
+ reg [7:0] datareg0_0;
+ reg [7:0] datareg0_1;
+ reg [7:0] datareg0_2;
+ reg [7:0] datareg0_3;
+
+ reg [7:0] datareg1_0;
+ reg [7:0] datareg1_1;
+ reg [7:0] datareg1_2;
+ reg [7:0] datareg1_3;
+
+ always @(posedge clk_i or negedge nrst_i)
+ if (~nrst_i) // reset registers
+ begin
+ datareg0_0 <= 8'h00;
+ datareg0_1 <= 8'h01;
+ datareg0_2 <= 8'h02;
+ datareg0_3 <= 8'h03;
+ datareg1_0 <= 8'h10;
+ datareg1_1 <= 8'h11;
+ datareg1_2 <= 8'h12;
+ datareg1_3 <= 8'h13;
+ end
+ else if(wb_wr) // wishbone write cycle
+ case (wb_sel_i)
+ 4'b0000:
+ case (wb_adr_i) // synopsys full_case parallel_case
+ 3'b000: datareg0_0 <= wb_dat_i[7:0];
+ 3'b001: datareg0_1 <= wb_dat_i[7:0];
+ 3'b010: datareg0_2 <= wb_dat_i[7:0];
+ 3'b011: datareg0_3 <= wb_dat_i[7:0];
+ 3'b100: datareg1_0 <= wb_dat_i[7:0];
+ 3'b101: datareg1_1 <= wb_dat_i[7:0];
+ 3'b110: datareg1_2 <= wb_dat_i[7:0];
+ 3'b111: datareg1_3 <= wb_dat_i[7:0];
+ endcase
+ 4'b0001:
+ case (wb_adr_i) // synopsys full_case parallel_case
+ 3'b000: datareg0_0 <= wb_dat_i[7:0];
+ 3'b001: datareg0_1 <= wb_dat_i[7:0];
+ 3'b010: datareg0_2 <= wb_dat_i[7:0];
+ 3'b011: datareg0_3 <= wb_dat_i[7:0];
+ 3'b100: datareg1_0 <= wb_dat_i[7:0];
+ 3'b101: datareg1_1 <= wb_dat_i[7:0];
+ 3'b110: datareg1_2 <= wb_dat_i[7:0];
+ 3'b111: datareg1_3 <= wb_dat_i[7:0];
+ endcase
+ 4'b0011:
+ {datareg0_1, datareg0_0} <= wb_dat_i[15:0];
+// case (wb_adr_i) // synopsys full_case parallel_case
+// 3'b000: {datareg0_1, datareg0_0} <= wb_dat_i[15:0];
+// endcase
+ 4'b1111:
+ {datareg0_3, datareg0_2, datareg0_1, datareg0_0} <= wb_dat_i[31:0];
+// case (wb_adr_i) // synopsys full_case parallel_case
+// 3'b000: {datareg0_3, datareg0_2, datareg0_1, datareg0_0} <= wb_dat_i[31:0];
+// endcase
+
+ endcase
+ //
+ // generate dat_o
+ always @(posedge clk_i)
+ case (wb_sel_i)
+ 4'b0000:
+ case (wb_adr_i) // synopsys full_case parallel_case
+ 3'b000: wb_dat_o[7:0] <= datareg0_0;
+ 3'b001: wb_dat_o[7:0] <= datareg0_1;
+ 3'b010: wb_dat_o[7:0] <= datareg0_2;
+ 3'b011: wb_dat_o[7:0] <= datareg0_3;
+ 3'b100: wb_dat_o[7:0] <= datareg1_0;
+ 3'b101: wb_dat_o[7:0] <= datareg1_1;
+ 3'b110: wb_dat_o[7:0] <= datareg1_2;
+ 3'b111: wb_dat_o[7:0] <= datareg1_3;
+ endcase
+ 4'b0001:
+ case (wb_adr_i) // synopsys full_case parallel_case
+ 3'b000: wb_dat_o[7:0] <= datareg0_0;
+ 3'b001: wb_dat_o[7:0] <= datareg0_1;
+ 3'b010: wb_dat_o[7:0] <= datareg0_2;
+ 3'b011: wb_dat_o[7:0] <= datareg0_3;
+ 3'b100: wb_dat_o[7:0] <= datareg1_0;
+ 3'b101: wb_dat_o[7:0] <= datareg1_1;
+ 3'b110: wb_dat_o[7:0] <= datareg1_2;
+ 3'b111: wb_dat_o[7:0] <= datareg1_3;
+ endcase
+ 4'b0011:
+ wb_dat_o[15:0] <= {datareg0_1, datareg0_0};
+ 4'b1111:
+ wb_dat_o[31:0] <= {datareg0_3, datareg0_2, datareg0_1, datareg0_0};
+ endcase
+
+ //
+ // generate ack_o
+ always @(posedge clk_i)
+ wb_ack_o <= #1 wb_acc & !wb_ack_o;
+
+ assign datareg0 = { datareg0_3, datareg0_2, datareg0_1, datareg0_0 };
+ assign datareg1 = { datareg1_3, datareg1_2, datareg1_1, datareg1_0 };
+
+endmodule
trunk/rtl/verilog/wb_regfile.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/rtl/verilog/wb_dreq_periph.v
===================================================================
--- trunk/rtl/verilog/wb_dreq_periph.v (nonexistent)
+++ trunk/rtl/verilog/wb_dreq_periph.v (revision 3)
@@ -0,0 +1,101 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// $Id: wb_dreq_periph.v,v 1.1 2008-03-02 20:46:40 hharte Exp $
+//// wb_dreq_periph.v - Wishbone DMA Requestor for LPC Peripheral////
+//// ////
+//// This file is part of the Wishbone LPC Bridge project ////
+//// http://www.opencores.org/projects/wb_lpc/ ////
+//// ////
+//// Author: ////
+//// - Howard M. Harte (hharte@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Howard M. Harte ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ns
+
+`include "../../rtl/verilog/wb_lpc_defines.v"
+
+module wb_dreq_periph(clk_i, nrst_i,
+ dma_chan_i, dma_req_i,
+ ldrq_o
+);
+ // Wishbone Slave Interface
+ input clk_i;
+ input nrst_i; // Active low reset.
+
+ // Private DMA Interface
+ input [2:0] dma_chan_i;
+ input dma_req_i;
+
+ // LPC Bus DMA Request Output
+ output reg ldrq_o;
+
+ reg [1:0] adr_cnt;
+ reg [3:0] state;
+
+ always @(posedge clk_i or negedge nrst_i)
+ if(~nrst_i)
+ begin
+ state <= `LDRQ_ST_IDLE;
+ ldrq_o <= 1'b1; // LDRQ# Idle
+ adr_cnt <= 2'b00;
+ end
+ else begin
+ case(state)
+ `LDRQ_ST_IDLE:
+ begin
+ if(dma_req_i) begin
+ ldrq_o <= 1'b0;
+ state <= `LDRQ_ST_ADDR;
+ adr_cnt <= 2'h2;
+ end
+ end
+ `LDRQ_ST_ADDR:
+ begin
+ ldrq_o <= dma_chan_i[adr_cnt];
+ adr_cnt <= adr_cnt - 1;
+
+ if(adr_cnt == 2'h0)
+ state <= `LDRQ_ST_ACT;
+ end
+ `LDRQ_ST_ACT:
+ begin
+ ldrq_o <= 1'b1;
+ state <= `LDRQ_ST_DONE;
+ end
+ `LDRQ_ST_DONE:
+ begin
+ ldrq_o <= 1'b1;
+ state <= `LDRQ_ST_IDLE;
+ end
+ endcase
+ end
+
+endmodule
+
+
\ No newline at end of file
trunk/rtl/verilog/wb_dreq_periph.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/wb_lpc_sim/tb_lpc_top.v
===================================================================
--- trunk/sim/wb_lpc_sim/tb_lpc_top.v (nonexistent)
+++ trunk/sim/wb_lpc_sim/tb_lpc_top.v (revision 3)
@@ -0,0 +1,425 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// tb_lpc_top.v ////
+//// ////
+//// This file is part of the Wishbone LPC Bridge project ////
+//// http://www.opencores.org/projects/wb_lpc/ ////
+//// ////
+//// Author: ////
+//// - Howard M. Harte (hharte@opencores.org) ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2008 Howard M. Harte ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`timescale 1 ns / 1 ns
+
+`include "../../rtl/verilog/wb_lpc_defines.v"
+
+// Define Module for Test Fixture
+module wb_lpc_master_bench();
+
+// LPC Host Inputs
+ reg clk_i;
+ reg nrst_i;
+ reg [31:0] wbs_adr_i;
+ reg [31:0] wbs_dat_i;
+ reg [3:0] wbs_sel_i;
+ reg [1:0] wbs_tga_i;
+ reg wbs_we_i;
+ reg wbs_stb_i;
+ reg wbs_cyc_i;
+ wire [3:0] lad_i;
+ reg [2:0] dma_chan_i;
+ reg dma_tc_i;
+
+// LPC Host Outputs
+ wire [31:0] wbs_dat_o;
+ wire wbs_ack_o;
+ wire lframe_o;
+ wire [3:0] lad_o;
+ wire lad_oe;
+
+// Bidirs
+ wire [3:0] lad_bus;
+
+// LPC Peripheral Inputs
+ wire [31:0] wbm_dat_i;
+ wire wbm_ack_i;
+
+// LPC Peripheral Outputs
+ wire [31:0] wbm_adr_o;
+ wire [31:0] wbm_dat_o;
+ wire [3:0] wbm_sel_o;
+ wire [1:0] wbm_tga_o;
+ wire wbm_we_o;
+ wire wbm_stb_o;
+ wire wbm_cyc_o;
+ wire [2:0] dma_chan_o;
+ wire dma_tc_o;
+
+ wire [3:0] slave_lad_i;
+ wire [3:0] slave_lad_o;
+
+ reg dma_req_i;
+
+task Reset;
+begin
+ nrst_i = 1; # 1000;
+ nrst_i = 0; # 1000;
+ nrst_i = 1; # 1000;
+end
+endtask
+
+
+task wb_write;
+ input reg [31:0] adr_i;
+ input reg [3:0] sel_i;
+ input reg [31:0] dat_i;
+ reg [7:0] wait_cnt;
+ begin
+
+ wbs_adr_i = adr_i;
+ wbs_sel_i = sel_i;
+ wbs_dat_i = dat_i;
+ wbs_stb_i = 1'b1;
+ wbs_cyc_i = 1'b1;
+ wbs_we_i = 1'b1;
+
+ wait_cnt = 0;
+
+ while ((wbs_ack_o == 0) & (wait_cnt < 100))
+ begin
+ wait_cnt = wait_cnt+1;
+ # 100;
+ end
+
+ if(wait_cnt == 100)
+ begin
+ $display($time, " Error, wb_w[%x/%x]: timeout waiting for ack", adr_i, dat_i); $stop(1);
+ end
+
+ wbs_stb_i = 1'b0;
+ wbs_cyc_i = 1'b0;
+ wbs_we_i = 1'b0;
+
+ end
+endtask
+
+
+task wb_read;
+ input reg [31:0] adr_i;
+ input reg [3:0] sel_i;
+ input reg [31:0] dat_i;
+ reg [7:0] wait_cnt;
+ begin
+
+ wbs_adr_i = adr_i;
+ wbs_sel_i = sel_i;
+ wbs_dat_i = 32'h0;
+ wbs_stb_i = 1'b1;
+ wbs_cyc_i = 1'b1;
+ wbs_we_i = 1'b0;
+
+ wait_cnt = 0;
+
+ while ((wbs_ack_o == 0) & (wait_cnt < 100))
+ begin
+ wait_cnt = wait_cnt+1;
+ # 100;
+ end
+
+ if(wait_cnt == 100)
+ begin
+ $display($time, " Error, wb_r[%x]: timeout waiting for ack", adr_i); $stop(1);
+ end
+
+ wbs_stb_i = 1'b0;
+ wbs_cyc_i = 1'b0;
+
+ if(dat_i != wbs_dat_o)
+ begin
+ $display($time, " Error, wb_r[%x]: expected %x, got %x", adr_i, dat_i, wbs_dat_o); $stop(1);
+ end
+
+ end
+endtask
+
+
+ always begin
+ #50 clk_i = 0;
+ #50 clk_i = 1;
+ end
+
+// Instantiate the UUT
+ wb_lpc_host UUT_Host (
+ .clk_i(clk_i),
+ .nrst_i(nrst_i),
+ .wbs_adr_i(wbs_adr_i),
+ .wbs_dat_o(wbs_dat_o),
+ .wbs_dat_i(wbs_dat_i),
+ .wbs_sel_i(wbs_sel_i),
+ .wbs_tga_i(wbs_tga_i),
+ .wbs_we_i(wbs_we_i),
+ .wbs_stb_i(wbs_stb_i),
+ .wbs_cyc_i(wbs_cyc_i),
+ .wbs_ack_o(wbs_ack_o),
+ .dma_chan_i(dma_chan_i),
+ .dma_tc_i(dma_tc_i),
+ .lframe_o(lframe_o),
+ .lad_i(lad_i),
+ .lad_o(lad_o),
+ .lad_oe(lad_oe)
+ );
+
+// Instantiate the module
+wb_lpc_periph UUT_Periph (
+ .clk_i(clk_i),
+ .nrst_i(nrst_i),
+ .wbm_adr_o(wbm_adr_o),
+ .wbm_dat_o(wbm_dat_o),
+ .wbm_dat_i(wbm_dat_i),
+ .wbm_sel_o(wbm_sel_o),
+ .wbm_tga_o(wbm_tga_o),
+ .wbm_we_o(wbm_we_o),
+ .wbm_stb_o(wbm_stb_o),
+ .wbm_cyc_o(wbm_cyc_o),
+ .wbm_ack_i(wbm_ack_i),
+ .dma_chan_o(dma_chan_o),
+ .dma_tc_o(dma_tc_o),
+ .lframe_i(lframe_o),
+ .lad_i(slave_lad_i),
+ .lad_o(slave_lad_o),
+ .lad_oe(slave_lad_oe)
+ );
+
+wire ldrq_o;
+wire [2:0] master_dma_chan_o;
+wire master_dma_req_o;
+
+// Instantiate the module
+wb_dreq_periph UUT_DREQ_Periph (
+ .clk_i(clk_i),
+ .nrst_i(nrst_i),
+ .dma_chan_i(dma_chan_i),
+ .dma_req_i(dma_req_i),
+ .ldrq_o(ldrq_o)
+ );
+
+// Instantiate the module
+wb_dreq_host UUT_DREQ_Host (
+ .clk_i(clk_i),
+ .nrst_i(nrst_i),
+ .dma_chan_o(master_dma_chan_o),
+ .dma_req_o(master_dma_req_o),
+ .ldrq_i(ldrq_o)
+ );
+
+wire [31:0] datareg0;
+wire [31:0] datareg1;
+
+// Instantiate the module
+wb_regfile regfile (
+ .clk_i(clk_i),
+ .nrst_i(nrst_i),
+ .wb_adr_i(wbm_adr_o),
+ .wb_dat_o(wbm_dat_i),
+ .wb_dat_i(wbm_dat_o),
+ .wb_sel_i(wbm_sel_o),
+ .wb_we_i(wbm_we_o),
+ .wb_stb_i(wbm_stb_o),
+ .wb_cyc_i(wbm_cyc_o),
+ .wb_ack_o(wbm_ack_i),
+ .datareg0(datareg0),
+ .datareg1(datareg1)
+ );
+
+assign lad_bus = lad_oe ? lad_o : (slave_lad_oe ? slave_lad_o : 4'bzzzz);
+assign lad_i = lad_bus;
+assign slave_lad_i = lad_bus;
+
+// Initialize Inputs
+ initial begin
+// $monitor("Time: %d clk_i=%b",
+// $time, clk_i);
+ clk_i = 0;
+ nrst_i = 1;
+ wbs_adr_i = 0;
+ wbs_dat_i = 0;
+ wbs_sel_i = 0;
+ wbs_tga_i = `WB_TGA_IO;
+ wbs_we_i = 0;
+ wbs_stb_i = 0;
+ wbs_cyc_i = 0;
+ dma_chan_i = 3'b0;
+ dma_tc_i = 0;
+ dma_req_i = 0;
+
+ Reset();
+
+ wbs_tga_i = `WB_TGA_IO;
+ $display($time, " Testing LPC I/O Accesses");
+ wb_write(32'h00000000, `WB_SEL_BYTE, 32'h00000012);
+ # 100;
+ wb_write(32'h00000001, `WB_SEL_BYTE, 32'h00000034);
+ # 100;
+ wb_write(32'h00000002, `WB_SEL_BYTE, 32'h00000056);
+ # 100;
+ wb_write(32'h00000003, `WB_SEL_BYTE, 32'h00000078);
+ # 100;
+ wb_write(32'h00000004, `WB_SEL_BYTE, 32'h0000009a);
+ # 100;
+ wb_write(32'h00000005, `WB_SEL_BYTE, 32'h000000bc);
+ # 100;
+ wb_write(32'h00000006, `WB_SEL_BYTE, 32'h000000de);
+ # 100;
+ wb_write(32'h00000007, `WB_SEL_BYTE, 32'h000000f0);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_BYTE, 32'hXXXXXX12);
+ # 100;
+ wb_read(32'h00000001, `WB_SEL_BYTE, 32'hXXXXXX34);
+ # 100;
+ wb_read(32'h00000002, `WB_SEL_BYTE, 32'hXXXXXX56);
+ # 100;
+ wb_read(32'h00000003, `WB_SEL_BYTE, 32'hXXXXXX78);
+ # 100;
+ wb_read(32'h00000004, `WB_SEL_BYTE, 32'hXXXXXX9a);
+ # 100;
+ wb_read(32'h00000005, `WB_SEL_BYTE, 32'hXXXXXXbc);
+ # 100;
+ wb_read(32'h00000006, `WB_SEL_BYTE, 32'hXXXXXXde);
+ # 100;
+ wb_read(32'h00000007, `WB_SEL_BYTE, 32'hXXXXXXf0);
+ # 100;
+
+
+ wbs_tga_i = `WB_TGA_MEM;
+ $display($time, " Testing LPC MEM Accesses");
+ wb_write(32'h00000000, `WB_SEL_BYTE, 32'h00000012);
+ # 100;
+ wb_write(32'h00000001, `WB_SEL_BYTE, 32'h00000034);
+ # 100;
+ wb_write(32'h00000002, `WB_SEL_BYTE, 32'h00000056);
+ # 100;
+ wb_write(32'h00000003, `WB_SEL_BYTE, 32'h00000078);
+ # 100;
+ wb_write(32'h00000004, `WB_SEL_BYTE, 32'h0000009a);
+ # 100;
+ wb_write(32'h00000005, `WB_SEL_BYTE, 32'h000000bc);
+ # 100;
+ wb_write(32'h00000006, `WB_SEL_BYTE, 32'h000000de);
+ # 100;
+ wb_write(32'h00000007, `WB_SEL_BYTE, 32'h000000f0);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_BYTE, 32'hXXXXXX12);
+ # 100;
+ wb_read(32'h00000001, `WB_SEL_BYTE, 32'hXXXXXX34);
+ # 100;
+ wb_read(32'h00000002, `WB_SEL_BYTE, 32'hXXXXXX56);
+ # 100;
+ wb_read(32'h00000003, `WB_SEL_BYTE, 32'hXXXXXX78);
+ # 100;
+ wb_read(32'h00000004, `WB_SEL_BYTE, 32'hXXXXXX9a);
+ # 100;
+ wb_read(32'h00000005, `WB_SEL_BYTE, 32'hXXXXXXbc);
+ # 100;
+ wb_read(32'h00000006, `WB_SEL_BYTE, 32'hXXXXXXde);
+ # 100;
+ wb_read(32'h00000007, `WB_SEL_BYTE, 32'hXXXXXXf0);
+ # 100;
+
+ wbs_tga_i = `WB_TGA_DMA;
+
+ $display($time, " Testing LPC DMA BYTE Accesses");
+ dma_chan_i = 3'h1;
+ wb_write(32'h00000000, `WB_SEL_BYTE, 32'hXXXXXX21);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_BYTE, 32'hXXXXXX21);
+ # 100;
+
+ $display($time, " Testing LPC DMA SHORT Accesses");
+ dma_chan_i = 3'h3;
+ wb_write(32'h00000000, `WB_SEL_SHORT, 32'hXXXX6543);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_SHORT, 32'hXXXX6543);
+ # 100;
+
+ $display($time, " Testing LPC DMA WORD Accesses");
+ dma_chan_i = 3'h7;
+ wb_write(32'h00000000, `WB_SEL_WORD, 32'hedcba987);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_WORD, 32'hedcba987);
+ # 100;
+
+ wbs_tga_i = `WB_TGA_FW;
+
+ $display($time, " Testing LPC Firmwre BYTE Accesses");
+ dma_chan_i = 3'h1;
+ wb_write(32'h00000000, `WB_SEL_BYTE, 32'hXXXXXX12);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_BYTE, 32'hXXXXXX12);
+ # 100;
+
+ $display($time, " Testing LPC Firmware SHORT Accesses");
+ dma_chan_i = 3'h3;
+ wb_write(32'h00000000, `WB_SEL_SHORT, 32'hXXXX3456);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_SHORT, 32'hXXXX3456);
+ # 100;
+
+ $display($time, " Testing LPC Firmware WORD Accesses");
+ dma_chan_i = 3'h7;
+ wb_write(32'h00000000, `WB_SEL_WORD, 32'h789abcde);
+ # 100;
+
+ wb_read(32'h00000000, `WB_SEL_WORD, 32'h789abcde);
+ # 100;
+
+ dma_req_i = 1;
+ # 100
+ dma_req_i = 0;
+ # 1000;
+
+ dma_chan_i = 3'b101;
+
+ dma_req_i = 1;
+ # 100
+ dma_req_i = 0;
+ # 1000;
+
+
+ $display($time, " Simulation passed"); $stop(1);
+
+end
+
+endmodule // wb_lpc_master_tf
trunk/sim/wb_lpc_sim/tb_lpc_top.v
Property changes :
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: trunk/sim/wb_lpc_sim/wb_lpc_sim.ise
===================================================================
--- trunk/sim/wb_lpc_sim/wb_lpc_sim.ise (nonexistent)
+++ trunk/sim/wb_lpc_sim/wb_lpc_sim.ise (revision 3)
@@ -0,0 +1,2171 @@
+PK
+
+ __OBJSTORE__/PK
+ __OBJSTORE__/common/PK
+ ' __OBJSTORE__/common/HierarchicalDesign/PK
+ T~ ~ 0 __OBJSTORE__/common/HierarchicalDesign/HDProject PK
+ ad d 7 __OBJSTORE__/common/HierarchicalDesign/HDProject_StrTbl
+ 1 4 /wb_lpc_host TS_EXPANDED TS_FRAGCOVERED TS_PACKED TS_ROUTED TS_SYNTHESIS wb_lpc_host PK
+ ";<