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

Subversion Repositories pss

[/] [pss/] [trunk/] [pss/] [hdl/] [pss/] [zpu_uc/] [motherblock/] [pss_sfr.v] - Rev 5

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

module PSS_SFR
#(
	parameter CPU_RESET_DEFAULT = 1,
	parameter A31_DEFAULT = 1,
	parameter MEM_SIZE_KB = 1
)
(
	input clk_i, rst_i,
 
	// bus controls
	input bus_enb_i,
	input bus_we_i,
	input [31:0] bus_wdata_bi,
	input [31:0] bus_addr_bi,
	input [3:0] bus_writemask_bi,
	output reg bus_ack_o,
	output reg [31:0] bus_rdata_bo,
 
	// special function signals
	input cpu_present_i,
	input cpu_break_i,
	input [31:0] cpu_pc_bi,
 
	input trap_cpu_enb_i,
	input [31:0] trap_cpu_addr_bi,
 
	output reg cpu_reset_o,
	output cpu_enb_o,
	output reg a31_o,
 
	input bus_error_i,
	input [31:0] bus_error_addr_bi,
 
	// interrupts
	output reg bus_error_int_o,
	output reg sgi_int_o,
	output reg trap_int_o,
 
	// interrupt controller signals
	input intc_ie_i,
	input [7:0] intc_pending_bi,
	output reg intc_ie_we_o,
	output reg intc_ie_data_o,
	output reg [7:0] intc_mask_bo,
	output reg intc_clr_cmd_o,
	output reg [7:0] intc_clr_code_bo,
 
	// DMA controls
	output reg dma_req_o,
	output reg dma_cmd_o,
	output reg dma_autoinc_o,
	output reg [31:0] dma_size_bo,
	output reg [31:0] dma_sourceaddr_bo,
	output reg [31:0] dma_destaddr_bo
);
 
//// System registers ////
localparam REG_CPU_CONTROL_ADDR		= 8'h00;
localparam REG_CPU_PC_ADDR 			= 8'h04;
localparam REG_A31					= 8'h08;
 
localparam REG_INTC_CONTROL_ADDR	= 8'h10;
localparam REG_INTC_MASK_ADDR		= 8'h14;
localparam REG_INTC_REQ_ADDR		= 8'h18;
localparam REG_MEM_SIZE_KB			= 8'h1C;
 
localparam REG_DMA_CONTROL_ADDR 	= 8'h20;
localparam REG_DMA_SOURCEADDR_ADDR 	= 8'h24;
localparam REG_DMA_DESTADDR_ADDR 	= 8'h28;
localparam REG_DMA_SIZE_ADDR 		= 8'h2C;
 
localparam REG_SGI_ADDR				= 8'h30;
 
localparam REG_BUS_ERROR_ADDR_ADDR	= 8'h38;
localparam REG_BUS_ERROR_PC_ADDR	= 8'h3C;
 
localparam REG_TRAP_CONTROL_ADDR	= 8'h40;
localparam REG_TRAP_ADDR_ADDR		= 8'h44;
 
assign cpu_enb_o = 1'b1;
 
reg trap_enable;
reg [31:0] trap_addr;
 
reg [31:0] bus_error_pc;
reg [31:0] bus_error_addr;
 
reg bus_ack_rd;
always @(posedge clk_i)
	begin
	if (rst_i) bus_ack_rd <= 1'b0;
	else if ((bus_enb_i == 1'b1) && (bus_we_i == 1'b0) && (bus_ack_rd == 1'b0)) bus_ack_rd <= 1'b1;
	else bus_ack_rd <= 1'b0;
	end
 
always @*
	begin
	if ((bus_enb_i == 1'b1) && (bus_we_i == 1'b1)) bus_ack_o = 1'b1;
	else bus_ack_o = bus_ack_rd;
	end
 
always @(posedge clk_i)
	begin
	if (rst_i)
		begin
 
		cpu_reset_o <= CPU_RESET_DEFAULT;
		a31_o <= A31_DEFAULT;
 
		trap_enable <= 1'b0;
		trap_addr <= 32'h0;
 
		sgi_int_o <= 1'b0;
 
		dma_req_o <= 1'b0;
		dma_cmd_o <= 1'b0;
		dma_autoinc_o <= 1'b0;
 
		intc_ie_we_o <= 1'b0;
		intc_ie_data_o <= 1'bx;
		intc_mask_bo <= 8'h0;
		intc_clr_cmd_o <= 1'b0;
		intc_clr_code_bo <= 8'hx;
 
		dma_sourceaddr_bo <= 32'h0;
		dma_destaddr_bo <= 32'h0;
		dma_size_bo <= 32'h0;
		end
	else
		begin
 
		sgi_int_o <= 1'b0;
 
		intc_ie_we_o <= 1'b0;
		intc_clr_cmd_o <= 1'b0;
		bus_rdata_bo <= 32'hx;
 
		dma_req_o <= 1'b0;
 
		if (bus_enb_i == 1'b1)
			begin
			if (bus_we_i == 1'b0)
				case (bus_addr_bi[7:0])
					REG_CPU_CONTROL_ADDR:		bus_rdata_bo <= {cpu_present_i, 29'h0, cpu_break_i, cpu_reset_o};
					REG_CPU_PC_ADDR:			bus_rdata_bo <= cpu_pc_bi;
					REG_A31:					bus_rdata_bo <= {31'h0, a31_o};
 
					REG_INTC_CONTROL_ADDR:		bus_rdata_bo <= {31'h0, intc_ie_i};
					REG_INTC_MASK_ADDR:			bus_rdata_bo <= {24'h0, intc_mask_bo};
					REG_INTC_REQ_ADDR:			bus_rdata_bo <= {24'h0, intc_pending_bi};
					REG_MEM_SIZE_KB:			bus_rdata_bo <= MEM_SIZE_KB;
 
					REG_DMA_SOURCEADDR_ADDR: 	bus_rdata_bo <= dma_sourceaddr_bo;
					REG_DMA_DESTADDR_ADDR: 		bus_rdata_bo <= dma_destaddr_bo;
					REG_DMA_SIZE_ADDR: 			bus_rdata_bo <= dma_size_bo;
 
					REG_TRAP_CONTROL_ADDR:		bus_rdata_bo <= {31'h0, trap_enable};
					REG_TRAP_ADDR_ADDR:			bus_rdata_bo <= trap_addr;
 
					REG_BUS_ERROR_ADDR_ADDR:	bus_rdata_bo <= bus_error_addr;
					REG_BUS_ERROR_PC_ADDR:		bus_rdata_bo <= bus_error_pc;
				endcase
			else
				case (bus_addr_bi[7:0])
					REG_CPU_CONTROL_ADDR:		cpu_reset_o <= bus_wdata_bi[0];
					REG_A31:					a31_o <= bus_wdata_bi[0];
 
					REG_INTC_CONTROL_ADDR:		begin intc_ie_we_o <= 1'b1; intc_ie_data_o <= bus_wdata_bi[0]; end
					REG_INTC_MASK_ADDR:			intc_mask_bo <= bus_wdata_bi[7:0];
					REG_INTC_REQ_ADDR:			begin intc_clr_cmd_o <= 1'b1; intc_clr_code_bo <= bus_wdata_bi[7:0]; end
 
					REG_DMA_CONTROL_ADDR:		begin dma_req_o <= 1'b1; dma_cmd_o <= bus_wdata_bi[1]; dma_autoinc_o <= bus_wdata_bi[2]; end
					REG_DMA_SOURCEADDR_ADDR: 	begin
													if (bus_wdata_bi[31] == 1'b1)
														dma_sourceaddr_bo <= {a31_o, bus_wdata_bi[30:0]};
													else 
														dma_sourceaddr_bo <= bus_wdata_bi;
												end
					REG_DMA_DESTADDR_ADDR: 		begin
 
													if (bus_wdata_bi[31] == 1'b1)
														dma_destaddr_bo <= {a31_o, bus_wdata_bi[30:0]};
													else 
														dma_destaddr_bo <= bus_wdata_bi;
												end
					REG_DMA_SIZE_ADDR: 			dma_size_bo <= bus_wdata_bi;
 
					REG_SGI_ADDR:				sgi_int_o <= 1'b1;
 
					REG_TRAP_CONTROL_ADDR:		trap_enable <= bus_wdata_bi[0];
					REG_TRAP_ADDR_ADDR:			trap_addr <= bus_wdata_bi;
				endcase
			end
		end
	end
 
// trap logic
always @(posedge clk_i)
	begin
	if (rst_i)
		trap_int_o <= 1'b0;
	else
		begin
		trap_int_o <= 1'b0;
		if (trap_enable == 1'b1)
			if (trap_cpu_enb_i == 1'b1)
				if (trap_cpu_addr_bi == trap_addr)
					trap_int_o <= 1'b1;
		end
	end
 
always @(posedge clk_i)
	begin
	if (rst_i)
		begin
		bus_error_int_o <= 1'b0;
		bus_error_addr <= 32'h0;
		bus_error_pc <= 32'h0;
		end
	else
		begin
		bus_error_int_o <= 1'b0;
		if (bus_error_i == 1'b1)
			begin
			bus_error_int_o <= 1'b1;
			bus_error_addr <= bus_error_addr_bi;
			bus_error_pc <= cpu_pc_bi;
			end 
		end
	end
 
endmodule
 

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.