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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_cp15_cb.v] - Diff between revs 26 and 43

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 26 Rev 43
Line 33... Line 33...
 
 
module zap_cp15_cb #(
module zap_cp15_cb #(
        parameter PHY_REGS = 64
        parameter PHY_REGS = 64
)
)
(
(
 
        // ----------------------------------------------------------------
        // Clock and reset.
        // Clock and reset.
 
        // ----------------------------------------------------------------
 
 
        input wire                              i_clk,
        input wire                              i_clk,
        input wire                              i_reset,
        input wire                              i_reset,
 
 
        //
        // ----------------------------------------------------------------
        // Coprocessor bus.
        // Coprocessor instruction and done signal.
        //
        // ----------------------------------------------------------------
 
 
        // Coprocessor instruction.
 
        input wire      [31:0]                  i_cp_word,
        input wire      [31:0]                  i_cp_word,
 
 
        // Coprocessor instruction valid.
 
        input wire                              i_cp_dav,
        input wire                              i_cp_dav,
 
 
        // Coprocessor done.
 
        output reg                              o_cp_done,
        output reg                              o_cp_done,
 
 
 
        // ----------------------------------------------------------------
        // CPSR from processor.
        // CPSR from processor.
 
        // ----------------------------------------------------------------
 
 
        input  wire     [31:0]                  i_cpsr,
        input  wire     [31:0]                  i_cpsr,
 
 
 
        // ----------------------------------------------------------------
 
        // Register file RW interface
 
        // ----------------------------------------------------------------
 
 
        // Asserted if we want to control of the register file.
        // Asserted if we want to control of the register file.
        // Controls a MUX that selects signals.
        // Controls a MUX that selects signals.
        output reg                              o_reg_en,
        output reg                              o_reg_en,
 
 
        // Data to write to the register file.
        // Data to write to the register file.
Line 67... Line 72...
 
 
        // Write and read index for the register file.
        // Write and read index for the register file.
        output reg [$clog2(PHY_REGS)-1:0]       o_reg_wr_index,
        output reg [$clog2(PHY_REGS)-1:0]       o_reg_wr_index,
                                                o_reg_rd_index,
                                                o_reg_rd_index,
 
 
        //
        // ----------------------------------------------------------------
        // From MMU.
        // From MMU.
        //
        // ----------------------------------------------------------------
 
 
        // The FSR stands for "Fault Status Register"
 
        // The FAR stands for "Fault Address Register"
 
        input wire      [31:0]                  i_fsr,
        input wire      [31:0]                  i_fsr,
        input wire      [31:0]                  i_far,
        input wire      [31:0]                  i_far,
 
 
        //
        // -----------------------------------------------------------------
        // These go to the MMU
        // MMU configuration signals.
        //
        // -----------------------------------------------------------------
 
 
        // COMMON TO BOTH DATA AND CODE MMU.
 
 
 
        // Domain Access Control Register.
        // Domain Access Control Register.
        output reg      [31:0]                  o_dac,
        output reg      [31:0]                  o_dac,
 
 
        // Base address of page table.
        // Base address of page table.
Line 94... Line 95...
        output reg                              o_mmu_en,
        output reg                              o_mmu_en,
 
 
        // SR register.
        // SR register.
        output reg      [1:0]                   o_sr,
        output reg      [1:0]                   o_sr,
 
 
        // SEPARATE SIGNALS FOR DATA AND CODE MMU.
        // FCSE register.
 
        output reg      [7:0]                   o_pid,
 
 
 
        // -----------------------------------------------------------------
 
        // Invalidate and clean controls.
 
        // -----------------------------------------------------------------
 
 
        // Cache invalidate signal.
        // Cache invalidate signal.
        output reg                              o_dcache_inv,
        output reg                              o_dcache_inv,
        output reg                              o_icache_inv,
        output reg                              o_icache_inv,
 
 
Line 125... Line 131...
 
 
`include "zap_localparams.vh"
`include "zap_localparams.vh"
`include "zap_defines.vh"
`include "zap_defines.vh"
`include "zap_functions.vh"
`include "zap_functions.vh"
 
 
 
// ---------------------------------------------
 
// Variables
 
// ---------------------------------------------
 
 
reg [31:0] r [6:0]; // Coprocessor registers. R7 is write-only.
reg [31:0] r [13:0];// Coprocessor registers. R7, R8 is write-only.
reg [3:0]    state; // State variable.
reg [3:0]    state; // State variable.
 
 
`ifndef SYNTHESIS
// ---------------------------------------------
integer ops;
// Localparams
initial ops = 0;
// ---------------------------------------------
`endif
 
 
 
// Ties registers to output ports via a register.
 
always @ (posedge i_clk)
 
begin
 
        if ( i_reset )
 
        begin
 
                o_dcache_en <= 0;
 
                o_icache_en <= 0;
 
                o_mmu_en    <= 0;
 
                o_dac       <= 32'dx;
 
                o_baddr     <= 32'dx;
 
                o_sr        <= 2'dx;
 
        end
 
        else
 
        begin
 
        o_dcache_en <= r[1][2];                  // Data cache enable.
 
        o_icache_en <= r[1][12];                 // Instruction cache enable.
 
        o_mmu_en    <= r[1][0];                  // MMU enable.
 
        o_dac       <= r[3];                     // DAC register.
 
        o_baddr     <= r[2];                      // Base address.               
 
        o_sr        <= {r[1][8],r[1][9]};         // SR register. 
 
        end
 
end
 
 
 
// States.
// States.
localparam IDLE                 = 0;
localparam IDLE                 = 0;
localparam ACTIVE               = 1;
localparam ACTIVE               = 1;
localparam DONE                 = 2;
localparam DONE                 = 2;
Line 177... Line 162...
// Register numbers.
// Register numbers.
localparam FSR_REG              = 5;
localparam FSR_REG              = 5;
localparam FAR_REG              = 6;
localparam FAR_REG              = 6;
localparam CACHE_REG            = 7;
localparam CACHE_REG            = 7;
localparam TLB_REG              = 8;
localparam TLB_REG              = 8;
 
localparam FCSE_REG             = 13;
 
 
//{opcode_2, crm} values that are valid for this implementation.
//{opcode_2, crm} values that are valid for this implementation.
localparam CASE_FLUSH_ID_CACHE       = 7'b000_0111;
localparam CASE_FLUSH_ID_CACHE       = 7'b000_0111;
localparam CASE_FLUSH_I_CACHE        = 7'b000_0101;
localparam CASE_FLUSH_I_CACHE        = 7'b000_0101;
localparam CASE_FLUSH_D_CACHE        = 7'b000_0110;
localparam CASE_FLUSH_D_CACHE        = 7'b000_0110;
Line 190... Line 176...
localparam CASE_CLFLUSH_D_CACHE      = 7'b000_1110;
localparam CASE_CLFLUSH_D_CACHE      = 7'b000_1110;
localparam CASE_FLUSH_ID_TLB         = 7'b000_0111;
localparam CASE_FLUSH_ID_TLB         = 7'b000_0111;
localparam CASE_FLUSH_I_TLB          = 7'b000_0101;
localparam CASE_FLUSH_I_TLB          = 7'b000_0101;
localparam CASE_FLUSH_D_TLB          = 7'b000_0110;
localparam CASE_FLUSH_D_TLB          = 7'b000_0110;
 
 
// Instruction fields.
// ---------------------------------------------
`define opcode_2        7:5
// Sequential Logic
`define crm             3:0
// ---------------------------------------------
`define crn             19:16
 
`define cp_id           11:8
// Ties registers to output ports via a register.
 
always @ ( posedge i_clk )
 
begin
 
        if ( i_reset )
 
        begin
 
                o_dcache_en <= 1'd0;
 
                o_icache_en <= 1'd0;
 
                o_mmu_en    <= 1'd0;
 
                o_dac       <= 32'dx;
 
                o_baddr     <= 32'dx;
 
                o_sr        <= 2'dx;
 
                o_pid       <= 8'd0;
 
        end
 
        else
 
        begin
 
                o_dcache_en <= r[1][2];                  // Data cache enable.
 
                o_icache_en <= r[1][12];                 // Instruction cache enable.
 
                o_mmu_en    <= r[1][0];                  // MMU enable.
 
                o_dac       <= r[3];                     // DAC register.
 
                o_baddr     <= r[2];                     // Base address.               
 
                o_sr        <= {r[1][8],r[1][9]};        // SR register. 
 
                o_pid       <= {1'd0, r[13][31:25]};     // PID register.
 
        end
 
end
 
 
 
// Core logic.
always @ (posedge i_clk)
always @ (posedge i_clk)
begin
begin
        if ( i_reset )
        if ( i_reset )
        begin
        begin
                state          <= IDLE;
                state          <= IDLE;
Line 212... Line 222...
                o_reg_en       <= 1'd0;
                o_reg_en       <= 1'd0;
                o_cp_done      <= 1'd0;
                o_cp_done      <= 1'd0;
                o_reg_wr_data  <= 0;
                o_reg_wr_data  <= 0;
                o_reg_wr_index <= 0;
                o_reg_wr_index <= 0;
                o_reg_rd_index <= 0;
                o_reg_rd_index <= 0;
 
 
                r[0]           <= 32'h0;
                r[0]           <= 32'h0;
                r[1]           <= 32'd0;
                r[1]           <= 32'd0;
                r[2]           <= 32'd0;
                r[2]           <= 32'd0;
                r[3]           <= 32'd0;
                r[3]           <= 32'd0;
                r[4]           <= 32'd0;
                r[4]           <= 32'd0;
                r[5]           <= 32'd0;
                r[5]           <= 32'd0;
                r[6]           <= 32'd0;
                r[6]           <= 32'd0;
 
                r[13]          <= 32'd0; //FCSE
 
 
 
                // R0 override.
 
                generate_r0;
 
 
                // Default values.
                // R1 override.
                r[0][23:16]     <= 32'h1;
 
                r[1][1]         <= 1'd1;
                r[1][1]         <= 1'd1;
                r[1][3]         <= 1'd1; // Write buffer always enabled.
                r[1][3]         <= 1'd1;
                r[1][7:4]       <= 4'b0011; // 0 = Little Endian, 0 = 0, 1 = 32-bit address range, 1 = 32-bit handlers enabled.
                r[1][6:4]       <= 3'b111;
                r[1][11]        <= 1'd1;
                r[1][11]        <= 1'd1;
                r[1][13]        <= 1'd0;
 
        end
        end
        else
        else
        begin
        begin
`ifndef SYNTHESIS
 
                ops             <= 0;
 
`endif
 
 
 
                // Default assignments.
                // Default assignments.
                o_itlb_inv      <= 1'd0;
                o_itlb_inv      <= 1'd0;
                o_dtlb_inv      <= 1'd0;
                o_dtlb_inv      <= 1'd0;
                o_dcache_inv    <= 1'd0;
                o_dcache_inv    <= 1'd0;
                o_icache_inv    <= 1'd0;
                o_icache_inv    <= 1'd0;
Line 307... Line 314...
                        begin
                        begin
                                case({i_cp_word[`opcode_2], i_cp_word[`crm]})
                                case({i_cp_word[`opcode_2], i_cp_word[`crm]})
 
 
                                        CASE_FLUSH_ID_TLB:
                                        CASE_FLUSH_ID_TLB:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 1;
 
`endif
 
                                                o_itlb_inv  <= 1'd1;
                                                o_itlb_inv  <= 1'd1;
                                                o_dtlb_inv  <= 1'd1;
                                                o_dtlb_inv  <= 1'd1;
                                        end
                                        end
 
 
                                        CASE_FLUSH_I_TLB:
                                        CASE_FLUSH_I_TLB:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 2;
 
`endif
 
                                                o_itlb_inv <= 1'd1;
                                                o_itlb_inv <= 1'd1;
                                        end
                                        end
 
 
                                        CASE_FLUSH_D_TLB:
                                        CASE_FLUSH_D_TLB:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 3;
 
`endif
 
                                                o_dtlb_inv <= 1'd1;
                                                o_dtlb_inv <= 1'd1;
                                        end
                                        end
 
 
                                        default:
                                        default:
                                        begin
                                        begin
                                                $display("Bad TLB command!");
                                                o_itlb_inv <= 1'd1;
                                                $finish;
                                                o_dtlb_inv <= 1'd1;
                                        end
                                        end
 
 
                                endcase
                                endcase
                        end
                        end
                        else if ( i_cp_word[`crn] == CACHE_REG ) // Cache control.
                        else if ( i_cp_word[`crn] == CACHE_REG ) // Cache control.
                        begin
                        begin
                                case({i_cp_word[`opcode_2], i_cp_word[`crm]})
                                case({i_cp_word[`opcode_2], i_cp_word[`crm]})
                                        CASE_FLUSH_ID_CACHE:
                                        CASE_FLUSH_ID_CACHE:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 4;
 
`endif
 
                                                // Invalidate caches.
                                                // Invalidate caches.
                                                o_dcache_inv    <= 1'd1;
                                                o_dcache_inv    <= 1'd1;
                                                state           <= CLR_D_CACHE_AND;
                                                state           <= CLR_D_CACHE_AND;
                                        end
                                        end
 
 
                                        CASE_FLUSH_D_CACHE:
                                        CASE_FLUSH_D_CACHE:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 5;
 
`endif
 
 
 
                                                // Invalidate data cache.
                                                // Invalidate data cache.
                                                o_dcache_inv    <= 1'd1;
                                                o_dcache_inv    <= 1'd1;
                                                state           <= CLR_D_CACHE;
                                                state           <= CLR_D_CACHE;
                                        end
                                        end
 
 
                                        CASE_FLUSH_I_CACHE:
                                        CASE_FLUSH_I_CACHE:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 6;
 
`endif
 
 
 
                                                // Invalidate instruction cache.
                                                // Invalidate instruction cache.
                                                o_icache_inv    <= 1'd1;
                                                o_icache_inv    <= 1'd1;
                                                state           <= CLR_I_CACHE;
                                                state           <= CLR_I_CACHE;
                                        end
                                        end
 
 
                                        CASE_CLEAN_ID_CACHE, CASE_CLEAN_D_CACHE:
                                        CASE_CLEAN_ID_CACHE, CASE_CLEAN_D_CACHE:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 7;
 
`endif
 
 
 
                                                o_dcache_clean <= 1'd1;
                                                o_dcache_clean <= 1'd1;
                                                state          <= CLEAN_D_CACHE;
                                                state          <= CLEAN_D_CACHE;
                                        end
                                        end
 
 
                                        CASE_CLFLUSH_D_CACHE:
                                        CASE_CLFLUSH_D_CACHE:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 8;
 
`endif
 
 
 
                                                o_dcache_clean <= 1'd1;
                                                o_dcache_clean <= 1'd1;
                                                state          <= CLFLUSH_D_CACHE;
                                                state          <= CLFLUSH_D_CACHE;
                                        end
                                        end
 
 
                                        CASE_CLFLUSH_ID_CACHE:
                                        CASE_CLFLUSH_ID_CACHE:
                                        begin
                                        begin
`ifndef SYNTHESIS
 
                                                ops <= 9;
 
`endif
 
 
 
                                                o_dcache_clean <= 1'd1;
                                                o_dcache_clean <= 1'd1;
                                                state          <= CLFLUSH_ID_CACHE;
                                                state          <= CLFLUSH_ID_CACHE;
                                        end
                                        end
 
 
                                        default:
                                        default:
                                        begin
                                        begin
                                        $display($time, "Error: Bad coprocessor instruction %b", i_cp_word);
                                                o_dcache_clean <= 1'd1;
                                        $finish;
                                                state          <= CLFLUSH_ID_CACHE;
                                        end
                                        end
 
 
                                endcase
                                endcase
                        end
                        end
                end
                end
Line 476... Line 456...
                begin
                begin
                        if ( is_cc_satisfied ( i_cp_word[31:28], i_cpsr[31:28] ) )
                        if ( is_cc_satisfied ( i_cp_word[31:28], i_cpsr[31:28] ) )
                        begin
                        begin
                                        if ( i_cp_word[20] ) // Load to CPU reg.
                                        if ( i_cp_word[20] ) // Load to CPU reg.
                                        begin
                                        begin
                                                // Register write command.
                                                // Generate CPU Register write command. CP read.
                                                o_reg_en        <= 1'd1;
                                                o_reg_en        <= 1'd1;
                                                o_reg_wr_index  <= translate( i_cp_word[15:12], i_cpsr[4:0] );
                                                o_reg_wr_index  <= translate( i_cp_word[15:12], i_cpsr[4:0] );
                                                o_reg_wr_data   <= r[ i_cp_word[19:16] ];
                                                o_reg_wr_data   <= r[ i_cp_word[19:16] ];
                                                state           <= DONE;
                                                state           <= DONE;
                                        end
                                        end
                                        else // Store to CPU register.
                                        else // Store to CPU register.
                                        begin
                                        begin
                                                // Generate register read command.
                                                // Generate CPU register read command. CP write.
                                                o_reg_en        <= 1'd1;
                                                o_reg_en        <= 1'd1;
                                                o_reg_rd_index  <= translate(i_cp_word[15:12], i_cpsr[4:0]);
                                                o_reg_rd_index  <= translate(i_cp_word[15:12], i_cpsr[4:0]);
                                                o_reg_wr_index  <= 16;
                                                o_reg_wr_index  <= 16;
                                                state           <= READ_DLY;
                                                state           <= READ_DLY;
                                        end
                                        end
                        end
                        end
                        else
                        else
                        begin
                        begin
                                state        <= DONE;
                                state        <= DONE;
                        end
                        end
 
 
 
                        // Process unconditional words to CP15.
 
                        casez ( i_cp_word )
 
                        MCR2, MRC2, LDC2, STC2:
 
                        begin
 
                                if ( i_cp_word[20] ) // Load to CPU reg.
 
                                begin
 
                                        // Register write command.
 
                                        o_reg_en        <= 1'd1;
 
                                        o_reg_wr_index  <= translate( i_cp_word[15:12], i_cpsr[4:0] );
 
                                        o_reg_wr_data   <= r[ i_cp_word[19:16] ];
 
                                        state           <= DONE;
 
                                end
 
                                else // Store to CPU register.
 
                                begin
 
                                        // Generate register read command.
 
                                        o_reg_en        <= 1'd1;
 
                                        o_reg_rd_index  <= translate(i_cp_word[15:12], i_cpsr[4:0]);
 
                                        o_reg_wr_index  <= 16;
 
                                        state           <= READ_DLY;
 
                                end
 
                        end
 
                        endcase
                end
                end
                endcase
                endcase
 
 
                // Default assignments. These bits are UNCHANGEABLE.
                // Default assignments. These bits are unchangeable.
                r[0][23:16]     <= 32'h1;
                generate_r0;
 
 
                r[1][1]         <= 1'd1;
                r[1][1]         <= 1'd1;
                r[1][3]         <= 1'd1; // Write buffer always enabled.
                r[1][3]         <= 1'd1; // Write buffer always enabled.
                r[1][7:4]       <= 4'b0011; // 0 = Little Endian, 0 = 0, 1 = 32-bit address range, 1 = 32-bit handlers enabled.
                r[1][6:4]       <= 3'b111;  // 0 = Little Endian, 0 = 0, 1 = 32-bit address range, 
 
                                            // 1 = 32-bit handlers enabled.
                r[1][11]        <= 1'd1;
                r[1][11]        <= 1'd1;
                r[1][13]        <= 1'd0;
 
        end
        end
end
end
 
 
`ifndef SYNTHESIS
// CPU info register.
// Debug only.
task generate_r0;
 
begin
 
        r[0][3:0]   <= 4'd0;
 
        r[0][15:4]  <= 12'hAAA;
 
        r[0][19:16] <= 4'h4;
 
        r[0][23:20] <= 4'd0;
 
        r[0][31:24] <= 8'd0;
 
end
 
endtask
 
 
 
// assertions_start
wire [31:0] r0 = r[0];
wire [31:0] r0 = r[0];
wire [31:0] r1 = r[1];
wire [31:0] r1 = r[1];
wire [31:0] r2 = r[2];
wire [31:0] r2 = r[2];
wire [31:0] r3 = r[3];
wire [31:0] r3 = r[3];
wire [31:0] r4 = r[4];
wire [31:0] r4 = r[4];
wire [31:0] r5 = r[5];
wire [31:0] r5 = r[5];
wire [31:0] r6 = r[6];
wire [31:0] r6 = r[6];
`endif
// assertions_end
 
 
endmodule
endmodule
`default_nettype wire
`default_nettype wire
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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