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

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [syntacore/] [scr1/] [src/] [top/] [scr1_imem_ahb.sv] - Diff between revs 11 and 21

Only display areas with differences | Details | Blame | View Log

Rev 11 Rev 21
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
/// @file       
/// @file       
/// @brief      Instruction memory AHB bridge
/// @brief      Instruction memory AHB bridge
///
///
`include "scr1_ahb.svh"
`include "scr1_ahb.svh"
`include "scr1_memif.svh"
`include "scr1_memif.svh"
module scr1_imem_ahb (
module scr1_imem_ahb (
    // Control Signals
    // Control Signals
    input   logic                           rst_n,
    input   logic                           rst_n,
    input   logic                           clk,
    input   logic                           clk,
    // Core Interface
    // Core Interface
    output  logic                           imem_req_ack,
    output  logic                           imem_req_ack,
    input   logic                           imem_req,
    input   logic                           imem_req,
    input   logic   [SCR1_AHB_WIDTH-1:0]    imem_addr,
    input   logic   [SCR1_AHB_WIDTH-1:0]    imem_addr,
    output  logic   [SCR1_AHB_WIDTH-1:0]    imem_rdata,
    output  logic   [SCR1_AHB_WIDTH-1:0]    imem_rdata,
    output  type_scr1_mem_resp_e            imem_resp,
    output  logic [1:0]                     imem_resp,
 
 
    // AHB Interface
    // AHB Interface
    output  logic   [3:0]                   hprot,
    output  logic   [3:0]                   hprot,
    output  logic   [2:0]                   hburst,
    output  logic   [2:0]                   hburst,
    output  logic   [2:0]                   hsize,
    output  logic   [2:0]                   hsize,
    output  logic   [1:0]                   htrans,
    output  logic   [1:0]                   htrans,
    output  logic                           hmastlock,
    output  logic                           hmastlock,
    output  logic   [SCR1_AHB_WIDTH-1:0]    haddr,
    output  logic   [SCR1_AHB_WIDTH-1:0]    haddr,
    input   logic                           hready,
    input   logic                           hready,
    input   logic   [SCR1_AHB_WIDTH-1:0]    hrdata,
    input   logic   [SCR1_AHB_WIDTH-1:0]    hrdata,
    input   logic                           hresp
    input   logic                           hresp
);
);
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Local parameters declaration
// Local parameters declaration
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
`ifndef SCR1_IMEM_AHB_OUT_BP
`ifndef SCR1_IMEM_AHB_OUT_BP
localparam  SCR1_FIFO_WIDTH = 2;
localparam  SCR1_FIFO_WIDTH = 2;
localparam  SCR1_FIFO_CNT_WIDTH = $clog2(SCR1_FIFO_WIDTH+1);
localparam  SCR1_FIFO_CNT_WIDTH = $clog2(SCR1_FIFO_WIDTH+1);
`endif // SCR1_IMEM_AHB_OUT_BP
`endif // SCR1_IMEM_AHB_OUT_BP
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Local types declaration
// Local types declaration
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
typedef enum logic {
typedef enum logic {
    SCR1_FSM_ADDR = 1'b0,
    SCR1_FSM_ADDR = 1'b0,
    SCR1_FSM_DATA = 1'b1,
    SCR1_FSM_DATA = 1'b1,
    SCR1_FSM_ERR  = 1'bx
    SCR1_FSM_ERR  = 1'bx
} type_scr1_fsm_e;
} type_scr1_fsm_e;
typedef struct packed {
typedef struct packed {
    logic   [SCR1_AHB_WIDTH-1:0]    haddr;
    logic   [SCR1_AHB_WIDTH-1:0]    haddr;
} type_scr1_req_fifo_s;
} type_scr1_req_fifo_s;
typedef struct packed {
typedef struct packed {
    logic                           hresp;
    logic                           hresp;
    logic   [SCR1_AHB_WIDTH-1:0]    hrdata;
    logic   [SCR1_AHB_WIDTH-1:0]    hrdata;
} type_scr1_resp_fifo_s;
} type_scr1_resp_fifo_s;
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Local signal declaration
// Local signal declaration
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
type_scr1_fsm_e                             fsm;
type_scr1_fsm_e                             fsm;
logic                                       req_fifo_rd;
logic                                       req_fifo_rd;
logic                                       req_fifo_wr;
logic                                       req_fifo_wr;
logic                                       req_fifo_up;
logic                                       req_fifo_up;
`ifdef SCR1_IMEM_AHB_OUT_BP
`ifdef SCR1_IMEM_AHB_OUT_BP
type_scr1_req_fifo_s                        req_fifo_r;
type_scr1_req_fifo_s                        req_fifo_r;
type_scr1_req_fifo_s [0:0]                  req_fifo;
type_scr1_req_fifo_s [0:0]                  req_fifo;
`else // SCR1_IMEM_AHB_OUT_BP
`else // SCR1_IMEM_AHB_OUT_BP
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo;
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo;
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo_new;
type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo_new;
logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt;
logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt;
logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt_new;
logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt_new;
`endif // SCR1_IMEM_AHB_OUT_BP
`endif // SCR1_IMEM_AHB_OUT_BP
logic                                       req_fifo_empty;
logic                                       req_fifo_empty;
logic                                       req_fifo_full;
logic                                       req_fifo_full;
type_scr1_resp_fifo_s                       resp_fifo;
type_scr1_resp_fifo_s                       resp_fifo;
logic                                       resp_fifo_hready;
logic                                       resp_fifo_hready;
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Interface to Core
// Interface to Core
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
assign imem_req_ack = ~req_fifo_full;
assign imem_req_ack = ~req_fifo_full;
assign req_fifo_wr  = ~req_fifo_full & imem_req;
assign req_fifo_wr  = ~req_fifo_full & imem_req;
assign imem_rdata = resp_fifo.hrdata;
assign imem_rdata = resp_fifo.hrdata;
assign imem_resp = (resp_fifo_hready)
assign imem_resp = (resp_fifo_hready)
                    ? (resp_fifo.hresp == SCR1_HRESP_OKAY)
                    ? (resp_fifo.hresp == SCR1_HRESP_OKAY)
                        ? SCR1_MEM_RESP_RDY_OK
                        ? SCR1_MEM_RESP_RDY_OK
                        : SCR1_MEM_RESP_RDY_ER
                        : SCR1_MEM_RESP_RDY_ER
                    : SCR1_MEM_RESP_NOTRDY;
                    : SCR1_MEM_RESP_NOTRDY;
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// REQ_FIFO
// REQ_FIFO
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
`ifdef SCR1_IMEM_AHB_OUT_BP
`ifdef SCR1_IMEM_AHB_OUT_BP
always_ff @(negedge rst_n, posedge clk) begin
always_ff @(negedge rst_n, posedge clk) begin
    if (~rst_n) begin
    if (~rst_n) begin
        req_fifo_full <= 1'b0;
        req_fifo_full <= 1'b0;
    end else begin
    end else begin
        if (~req_fifo_full) begin
        if (~req_fifo_full) begin
            req_fifo_full <= imem_req & ~req_fifo_rd;
            req_fifo_full <= imem_req & ~req_fifo_rd;
        end else begin
        end else begin
            req_fifo_full <= ~req_fifo_rd;
            req_fifo_full <= ~req_fifo_rd;
        end
        end
    end
    end
end
end
assign req_fifo_empty = ~(req_fifo_full | imem_req);
assign req_fifo_empty = ~(req_fifo_full | imem_req);
assign req_fifo_up    = ~req_fifo_rd & req_fifo_wr;
assign req_fifo_up    = ~req_fifo_rd & req_fifo_wr;
always_ff @(posedge clk) begin
always_ff @(posedge clk) begin
    if (req_fifo_up) begin
    if (req_fifo_up) begin
        req_fifo_r.haddr <= imem_addr;
        req_fifo_r.haddr <= imem_addr;
    end
    end
end
end
assign req_fifo[0] = (req_fifo_full) ? req_fifo_r : imem_addr;
assign req_fifo[0] = (req_fifo_full) ? req_fifo_r : imem_addr;
`else // SCR1_IMEM_AHB_OUT_BP
`else // SCR1_IMEM_AHB_OUT_BP
always_comb begin
always_comb begin
    req_fifo_up      = 1'b0;
    req_fifo_up      = 1'b0;
    req_fifo_cnt_new = req_fifo_cnt;
    req_fifo_cnt_new = req_fifo_cnt;
    req_fifo_new     = req_fifo;
    req_fifo_new     = req_fifo;
    case ({req_fifo_rd, req_fifo_wr})
    case ({req_fifo_rd, req_fifo_wr})
        2'b00 : begin
        2'b00 : begin
            // nothing todo
            // nothing todo
        end
        end
        2'b01: begin
        2'b01: begin
            // FIFO write
            // FIFO write
            req_fifo_up = 1'b1;
            req_fifo_up = 1'b1;
            req_fifo_new[req_fifo_cnt].haddr  = imem_addr;
            req_fifo_new[req_fifo_cnt].haddr  = imem_addr;
            req_fifo_cnt_new = req_fifo_cnt + 1'b1;
            req_fifo_cnt_new = req_fifo_cnt + 1'b1;
        end
        end
        2'b10 : begin
        2'b10 : begin
            // FIFO read
            // FIFO read
            req_fifo_up     = 1'b1;
            req_fifo_up     = 1'b1;
            req_fifo_new[0] = req_fifo_new[1];
            req_fifo_new[0] = req_fifo_new[1];
            req_fifo_new[1].haddr  = 'x;
            req_fifo_new[1].haddr  = 'x;
            req_fifo_cnt_new = req_fifo_cnt - 1'b1;
            req_fifo_cnt_new = req_fifo_cnt - 1'b1;
        end
        end
        2'b11 : begin
        2'b11 : begin
            // Read and Write FIFO. It is possible only when fifo_cnt = 1
            // Read and Write FIFO. It is possible only when fifo_cnt = 1
            req_fifo_up           = 1'b1;
            req_fifo_up           = 1'b1;
            req_fifo_new[0].haddr = imem_addr;
            req_fifo_new[0].haddr = imem_addr;
        end
        end
        default : begin
        default : begin
            req_fifo_up      = 'x;
            req_fifo_up      = 'x;
            req_fifo_cnt_new = 'x;
            req_fifo_cnt_new = 'x;
            req_fifo_new     = 'x;
            req_fifo_new     = 'x;
        end
        end
    endcase
    endcase
end
end
always_ff @(negedge rst_n, posedge clk) begin
always_ff @(negedge rst_n, posedge clk) begin
    if (~rst_n) begin
    if (~rst_n) begin
        req_fifo_cnt <= '0;
        req_fifo_cnt <= '0;
    end else begin
    end else begin
        if (req_fifo_up) begin
        if (req_fifo_up) begin
            req_fifo_cnt <= req_fifo_cnt_new;
            req_fifo_cnt <= req_fifo_cnt_new;
        end
        end
    end
    end
end
end
assign req_fifo_full  = (req_fifo_cnt == SCR1_FIFO_WIDTH);
assign req_fifo_full  = (req_fifo_cnt == SCR1_FIFO_WIDTH);
assign req_fifo_empty = ~(|req_fifo_cnt);
assign req_fifo_empty = ~(|req_fifo_cnt);
always_ff @(posedge clk) begin
always_ff @(posedge clk) begin
    if (req_fifo_up) begin
    if (req_fifo_up) begin
        req_fifo <= req_fifo_new;
        req_fifo <= req_fifo_new;
    end
    end
end
end
`endif // SCR1_IMEM_AHB_OUT_BP
`endif // SCR1_IMEM_AHB_OUT_BP
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// FSM
// FSM
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
always_ff @(negedge rst_n, posedge clk) begin
always_ff @(negedge rst_n, posedge clk) begin
    if (~rst_n) begin
    if (~rst_n) begin
        fsm <= SCR1_FSM_ADDR;
        fsm <= SCR1_FSM_ADDR;
    end else begin
    end else begin
        case (fsm)
        case (fsm)
            SCR1_FSM_ADDR : begin
            SCR1_FSM_ADDR : begin
                if (hready) begin
                if (hready) begin
                    fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
                    fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
                end
                end
            end
            end
            SCR1_FSM_DATA : begin
            SCR1_FSM_DATA : begin
                if (hready) begin
                if (hready) begin
                    if (hresp == SCR1_HRESP_OKAY) begin
                    if (hresp == SCR1_HRESP_OKAY) begin
                        fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
                        fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
                    end else begin
                    end else begin
                        fsm <= SCR1_FSM_ADDR;
                        fsm <= SCR1_FSM_ADDR;
                    end
                    end
                end
                end
            end
            end
            default : begin
            default : begin
                fsm <= SCR1_FSM_ERR;
                fsm <= SCR1_FSM_ERR;
            end
            end
        endcase
        endcase
    end
    end
end
end
always_comb begin
always_comb begin
    req_fifo_rd = 1'b0;
    req_fifo_rd = 1'b0;
    case (fsm)
    case (fsm)
        SCR1_FSM_ADDR : begin
        SCR1_FSM_ADDR : begin
            if (hready) begin
            if (hready) begin
                req_fifo_rd = ~req_fifo_empty;
                req_fifo_rd = ~req_fifo_empty;
            end
            end
        end
        end
        SCR1_FSM_DATA : begin
        SCR1_FSM_DATA : begin
            if (hready) begin
            if (hready) begin
                req_fifo_rd = ~req_fifo_empty & (hresp == SCR1_HRESP_OKAY);
                req_fifo_rd = ~req_fifo_empty & (hresp == SCR1_HRESP_OKAY);
            end
            end
        end
        end
        default : begin
        default : begin
            req_fifo_rd = 1'bx;
            req_fifo_rd = 1'bx;
        end
        end
    endcase
    endcase
end
end
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// FIFO response
// FIFO response
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
`ifdef SCR1_IMEM_AHB_IN_BP
`ifdef SCR1_IMEM_AHB_IN_BP
assign resp_fifo_hready = (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
assign resp_fifo_hready = (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
assign resp_fifo.hresp  = hresp;
assign resp_fifo.hresp  = hresp;
assign resp_fifo.hrdata = hrdata;
assign resp_fifo.hrdata = hrdata;
`else // SCR1_IMEM_AHB_IN_BP
`else // SCR1_IMEM_AHB_IN_BP
always_ff @(negedge rst_n, posedge clk) begin
always_ff @(negedge rst_n, posedge clk) begin
    if (~rst_n) begin
    if (~rst_n) begin
        resp_fifo_hready <= 1'b0;
        resp_fifo_hready <= 1'b0;
    end else begin
    end else begin
        resp_fifo_hready <= (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
        resp_fifo_hready <= (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
    end
    end
end
end
always_ff @(posedge clk) begin
always_ff @(posedge clk) begin
    if (hready & (fsm == SCR1_FSM_DATA)) begin
    if (hready & (fsm == SCR1_FSM_DATA)) begin
        resp_fifo.hresp  <= hresp;
        resp_fifo.hresp  <= hresp;
        resp_fifo.hrdata <= hrdata;
        resp_fifo.hrdata <= hrdata;
    end
    end
end
end
`endif // SCR1_IMEM_AHB_IN_BP
`endif // SCR1_IMEM_AHB_IN_BP
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Interface to AHB
// Interface to AHB
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
assign hprot[SCR1_HPROT_DATA]  = 1'b0;
assign hprot[SCR1_HPROT_DATA]  = 1'b0;
assign hprot[SCR1_HPROT_PRV]   = 1'b0;
assign hprot[SCR1_HPROT_PRV]   = 1'b0;
assign hprot[SCR1_HPROT_BUF]   = 1'b0;
assign hprot[SCR1_HPROT_BUF]   = 1'b0;
assign hprot[SCR1_HPROT_CACHE] = 1'b0;
assign hprot[SCR1_HPROT_CACHE] = 1'b0;
assign hburst       = SCR1_HBURST_SINGLE;
assign hburst       = SCR1_HBURST_SINGLE;
assign hsize        = SCR1_HSIZE_32B;
assign hsize        = SCR1_HSIZE_32B;
assign hmastlock    = 1'b0;
assign hmastlock    = 1'b0;
always_comb begin
always_comb begin
    htrans = SCR1_HTRANS_IDLE;
    htrans = SCR1_HTRANS_IDLE;
    case (fsm)
    case (fsm)
        SCR1_FSM_ADDR : begin
        SCR1_FSM_ADDR : begin
            if (~req_fifo_empty) begin
            if (~req_fifo_empty) begin
                htrans = SCR1_HTRANS_NONSEQ;
                htrans = SCR1_HTRANS_NONSEQ;
            end
            end
        end
        end
        SCR1_FSM_DATA : begin
        SCR1_FSM_DATA : begin
            if (hready) begin
            if (hready) begin
                if (hresp == SCR1_HRESP_OKAY) begin
                if (hresp == SCR1_HRESP_OKAY) begin
                    if (~req_fifo_empty) begin
                    if (~req_fifo_empty) begin
                        htrans = SCR1_HTRANS_NONSEQ;
                        htrans = SCR1_HTRANS_NONSEQ;
                    end
                    end
                end
                end
            end
            end
        end
        end
        default : begin
        default : begin
            htrans = SCR1_HTRANS_ERR;
            htrans = SCR1_HTRANS_ERR;
        end
        end
    endcase
    endcase
end
end
assign haddr  = req_fifo[0].haddr;
assign haddr  = req_fifo[0].haddr;
`ifdef SCR1_TRGT_SIMULATION
`ifdef SCR1_TRGT_SIMULATION
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Assertion
// Assertion
//-------------------------------------------------------------------------------
//-------------------------------------------------------------------------------
// Check Core interface
// Check Core interface
SCR1_SVA_IMEM_AHB_BRIDGE_REQ_XCHECK : assert property (
SCR1_SVA_IMEM_AHB_BRIDGE_REQ_XCHECK : assert property (
    @(negedge clk) disable iff (~rst_n)
    @(negedge clk) disable iff (~rst_n)
    !$isunknown(imem_req)
    !$isunknown(imem_req)
    ) else $error("IMEM AHB bridge Error: imem_req has unknown values");
    ) else $error("IMEM AHB bridge Error: imem_req has unknown values");
SCR1_IMEM_AHB_BRIDGE_ADDR_XCHECK : assert property (
SCR1_IMEM_AHB_BRIDGE_ADDR_XCHECK : assert property (
    @(negedge clk) disable iff (~rst_n)
    @(negedge clk) disable iff (~rst_n)
    imem_req |-> !$isunknown(imem_addr)
    imem_req |-> !$isunknown(imem_addr)
    ) else $error("IMEM AHB bridge Error: imem_addr has unknown values");
    ) else $error("IMEM AHB bridge Error: imem_addr has unknown values");
SCR1_IMEM_AHB_BRIDGE_ADDR_ALLIGN : assert property (
SCR1_IMEM_AHB_BRIDGE_ADDR_ALLIGN : assert property (
    @(negedge clk) disable iff (~rst_n)
    @(negedge clk) disable iff (~rst_n)
    imem_req |-> (imem_addr[1:0] == '0)
    imem_req |-> (imem_addr[1:0] == '0)
    ) else $error("IMEM AHB bridge Error: imem_addr has unalign values");
    ) else $error("IMEM AHB bridge Error: imem_addr has unalign values");
// Check AHB interface
// Check AHB interface
SCR1_IMEM_AHB_BRIDGE_HREADY_XCHECK : assert property (
SCR1_IMEM_AHB_BRIDGE_HREADY_XCHECK : assert property (
    @(negedge clk) disable iff (~rst_n)
    @(negedge clk) disable iff (~rst_n)
    !$isunknown(hready)
    !$isunknown(hready)
    ) else $error("IMEM AHB bridge Error: hready has unknown values");
    ) else $error("IMEM AHB bridge Error: hready has unknown values");
SCR1_IMEM_AHB_BRIDGE_HRESP_XCHECK : assert property (
SCR1_IMEM_AHB_BRIDGE_HRESP_XCHECK : assert property (
    @(negedge clk) disable iff (~rst_n)
    @(negedge clk) disable iff (~rst_n)
    !$isunknown(hresp)
    !$isunknown(hresp)
    ) else $error("IMEM AHB bridge Error: hresp has unknown values");
    ) else $error("IMEM AHB bridge Error: hresp has unknown values");
`endif // SCR1_TRGT_SIMULATION
`endif // SCR1_TRGT_SIMULATION
endmodule : scr1_imem_ahb
endmodule : scr1_imem_ahb
 
 

powered by: WebSVN 2.1.0

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