URL
https://opencores.org/ocsvn/pss/pss/trunk
Subversion Repositories pss
[/] [pss/] [trunk/] [pss/] [hdl/] [pss/] [zpu_uc/] [motherblock/] [pss_sfr.v] - Rev 7
Compare with Previous | Blame | View Log
module PSS_SFR #( parameter CPU_RESET_DEFAULT = 1, parameter EXT_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 reg ext_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; ext_reset_o <= EXT_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, 28'h0, cpu_break_i, ext_reset_o, 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: begin cpu_reset_o <= bus_wdata_bi[0]; ext_reset_o <= bus_wdata_bi[1]; end 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