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

Subversion Repositories light8080

[/] [light8080/] [trunk/] [verilog/] [rtl/] [l80soc.v] - Rev 71

Go to most recent revision | Compare with Previous | Blame | View Log

//---------------------------------------------------------------------------------------
//	Project:			light8080 SOC		WiCores Solutions 
//
//	File name:			l80soc.v 			(February 04, 2012)
//
//	Writer:				Moti Litochevski 
//
//	Description:
//		This file contains the light8080 System On a Chip (SOC). the system includes the 
//		CPU, program and data RAM and a UART interface and a general purpose digital IO. 
//
//	Revision History:
//
//	Rev <revnumber>			<Date>			<owner> 
//		<comment>
// 
//---------------------------------------------------------------------------------------
// 
//	Copyright (C) 2012 Moti Litochevski 
// 
//	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 PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, 
//	INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND 
//	FITNESS FOR A PARTICULAR PURPOSE. 
// 
//---------------------------------------------------------------------------------------
 
module l80soc 
(
	clock, reset,
	txd, rxd,
	p1dio, p2dio, 
	extint 
);
//---------------------------------------------------------------------------------------
// module interfaces 
// global signals 
input 			clock;		// global clock input 
input 			reset;		// global reset input 
// uart serial signals 
output			txd;		// serial data output 
input			rxd;		// serial data input 
// digital IO ports 
inout	[7:0]	p1dio;		// port 1 digital IO 
inout	[7:0]	p2dio;		// port 2 digital IO 
// external interrupt sources 
input	[3:0]	extint;		// external interrupt sources 
 
//---------------------------------------------------------------------------------------
// io space registers addresses 
// uart registers 
`define UDATA_REG			8'h80 		// used for both transmit and receive 
`define UBAUDL_REG			8'h81		// low byte of baud rate register 
`define UBAUDH_REG			8'h82		// low byte of baud rate register 
`define USTAT_REG			8'h83		// uart status register 
// dio port registers 
`define P1_DATA_REG			8'h84		// port 1 data register 
`define P1_DIR_REG			8'h85		// port 1 direction register 
`define P2_DATA_REG			8'h86		// port 2 data register 
`define P2_DIR_REG			8'h87		// port 2 direction register 
// interrupt controller register 
`define INTR_EN_REG			8'h88		// interrupts enable register 
 
//---------------------------------------------------------------------------------------
// internal declarations 
// registered output 
 
// internals 
wire [15:0] cpu_addr;
wire [7:0] cpu_din, cpu_dout, ram_dout, intr_dout;
wire cpu_io, cpu_rd, cpu_wr, cpu_inta, cpu_inte, cpu_intr; 
wire [7:0] txData, rxData;
wire txValid, txBusy, rxValid;
reg [15:0] uartbaud;
reg rxfull, scpu_io;
reg [7:0] p1reg, p1dir, p2reg, p2dir, io_dout;
reg [3:0] intr_ena;
 
//---------------------------------------------------------------------------------------
// module implementation 
// light8080 CPU instance 
light8080 cpu 
(  
	.clk(clock), 
	.reset(reset), 
	.addr_out(cpu_addr), 
	.vma(/* nu */), 
	.io(cpu_io), 
	.rd(cpu_rd), 
	.wr(cpu_wr), 
	.fetch(/* nu */), 
	.data_in(cpu_din), 
	.data_out(cpu_dout), 
	.inta(cpu_inta), 
	.inte(cpu_inte), 
	.halt(/* nu */), 
	.intr(cpu_intr) 
);
// cpu data input selection 
assign cpu_din = (cpu_inta) ? intr_dout : (scpu_io) ? io_dout : ram_dout;
 
// program and data Xilinx RAM memory 
ram_image ram 
(
	.clk(clock), 
	.addr(cpu_addr[11:0]), 
	.we(cpu_wr & ~cpu_io), 
	.din(cpu_dout), 
	.dout(ram_dout) 
);
 
// io space write registers 
always @ (posedge reset or posedge clock) 
begin 
	if (reset) 
	begin 
		uartbaud <= 16'b0;
		rxfull <= 1'b0;
		p1reg <= 8'b0;
		p1dir <= 8'b0;
		p2reg <= 8'b0;
		p2dir <= 8'b0;
		intr_ena <= 4'b0;
	end 
	else 
	begin 
		// io space registers 
		if (cpu_wr && cpu_io) 
		begin 
			if (cpu_addr[7:0] == `UBAUDL_REG)	uartbaud[7:0] <= cpu_dout;
			if (cpu_addr[7:0] == `UBAUDH_REG)	uartbaud[15:8] <= cpu_dout;
			if (cpu_addr[7:0] == `P1_DATA_REG)	p1reg <= cpu_dout;
			if (cpu_addr[7:0] == `P1_DIR_REG)	p1dir <= cpu_dout;
			if (cpu_addr[7:0] == `P2_DATA_REG)	p2reg <= cpu_dout;
			if (cpu_addr[7:0] == `P2_DIR_REG)	p2dir <= cpu_dout;
			if (cpu_addr[7:0] == `INTR_EN_REG)	intr_ena <= cpu_dout[3:0];
		end 
 
		// receiver full flag 
		if (rxValid && !rxfull) 
			rxfull <= 1'b1;
		else if (cpu_rd && cpu_io && (cpu_addr[7:0] == `UDATA_REG) && rxfull)
			rxfull <= 1'b0;
	end 
end 
// uart transmit write pulse 
assign txValid = cpu_wr & cpu_io & (cpu_addr[7:0] == `UDATA_REG);
 
// io space read registers 
always @ (posedge reset or posedge clock) 
begin 
	if (reset) 
	begin 
		io_dout <= 8'b0;
	end 
	else 
	begin 
		// io space read registers 
		if (cpu_io && (cpu_addr[7:0] == `UDATA_REG))
			io_dout <= rxData;
		else if (cpu_io && (cpu_addr[7:0] == `USTAT_REG))
			io_dout <= {3'b0, rxfull, 3'b0, txBusy};
		else if (cpu_io && (cpu_addr[7:0] == `P1_DATA_REG))
			io_dout <= p1dio;
		else if (cpu_io && (cpu_addr[7:0] == `P2_DATA_REG))
			io_dout <= p2dio;
 
		// sampled io control to select cpu data input 
		scpu_io <= cpu_io;
	end 
end 
 
// interrupt controller 
intr_ctrl intrc 
(
	.clock(clock), 
	.reset(reset),
	.ext_intr(extint), 
	.cpu_intr(cpu_intr), 
	.cpu_inte(cpu_inte), 
	.cpu_inta(cpu_inta), 
	.cpu_rd(cpu_rd), 
	.cpu_inst(intr_dout), 
	.intr_ena(intr_ena) 
);
 
// uart module mapped to the io space 
uart uart 
(
	.clock(clock), 
	.reset(reset),
	.serIn(rxd), 
	.serOut(txd),
	.txData(cpu_dout), 
	.txValid(txValid), 
	.txBusy(txBusy), 
	.txDone(/* nu */), 
	.rxData(rxData), 
	.rxValid(rxValid), 
	.baudDiv(uartbaud)
);
 
// digital IO ports 
// port 1 
assign p1dio[0] = p1dir[0] ? p1reg[0] : 1'bz;
assign p1dio[1] = p1dir[1] ? p1reg[1] : 1'bz;
assign p1dio[2] = p1dir[2] ? p1reg[2] : 1'bz;
assign p1dio[3] = p1dir[3] ? p1reg[3] : 1'bz;
assign p1dio[4] = p1dir[4] ? p1reg[4] : 1'bz;
assign p1dio[5] = p1dir[5] ? p1reg[5] : 1'bz;
assign p1dio[6] = p1dir[6] ? p1reg[6] : 1'bz;
assign p1dio[7] = p1dir[7] ? p1reg[7] : 1'bz;
// port 2 
assign p2dio[0] = p2dir[0] ? p2reg[0] : 1'bz;
assign p2dio[1] = p2dir[1] ? p2reg[1] : 1'bz;
assign p2dio[2] = p2dir[2] ? p2reg[2] : 1'bz;
assign p2dio[3] = p2dir[3] ? p2reg[3] : 1'bz;
assign p2dio[4] = p2dir[4] ? p2reg[4] : 1'bz;
assign p2dio[5] = p2dir[5] ? p2reg[5] : 1'bz;
assign p2dio[6] = p2dir[6] ? p2reg[6] : 1'bz;
assign p2dio[7] = p2dir[7] ? p2reg[7] : 1'bz;
 
endmodule
//---------------------------------------------------------------------------------------
//						Th.. Th.. Th.. Thats all folks !!!
//---------------------------------------------------------------------------------------
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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