Line 57... |
Line 57... |
// synopsys translate_on
|
// synopsys translate_on
|
`include "or1200_defines.v"
|
`include "or1200_defines.v"
|
|
|
module or1200_dpram
|
module or1200_dpram
|
(
|
(
|
|
rst,
|
// Generic synchronous double-port RAM interface
|
// Generic synchronous double-port RAM interface
|
clk_a, ce_a, addr_a, do_a,
|
clk_a, ce_a, addr_a, do_a,
|
clk_b, ce_b, we_b, addr_b, di_b
|
clk_b, ce_b, we_b, addr_b, di_b
|
`ifdef OR1200_RAM_PARITY
|
`ifdef OR1200_RAM_PARITY
|
, p_err
|
, p_err
|
Line 74... |
Line 75... |
parameter dw = 32;
|
parameter dw = 32;
|
|
|
//
|
//
|
// Generic synchronous double-port RAM interface
|
// Generic synchronous double-port RAM interface
|
//
|
//
|
|
input rst; // Reset
|
input clk_a; // Clock
|
input clk_a; // Clock
|
input ce_a; // Chip enable input
|
input ce_a; // Chip enable input
|
input [aw-1:0] addr_a; // address bus inputs
|
input [aw-1:0] addr_a; // address bus inputs
|
output [dw-1:0] do_a; // output data bus
|
output [dw-1:0] do_a; // output data bus
|
input clk_b; // Clock
|
input clk_b; // Clock
|
Line 99... |
Line 101... |
|
|
//
|
//
|
// Generic RAM's registers and wires
|
// Generic RAM's registers and wires
|
//
|
//
|
`ifdef OR1200_RAM_PARITY
|
`ifdef OR1200_RAM_PARITY
|
reg [(dw+(dw/8))-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/; // RAM content
|
parameter par_w = (dw/8);
|
|
|
|
reg [(dw+par_w)-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/; // RAM content
|
`else
|
`else
|
reg [dw-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/; // RAM content
|
reg [dw-1:0] mem [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/; // RAM content
|
`endif
|
`endif
|
reg [aw-1:0] addr_a_reg; // RAM address registered
|
reg [aw-1:0] addr_a_reg; // RAM address registered
|
|
|
`ifdef OR1200_RAM_PARITY
|
`ifdef OR1200_RAM_PARITY
|
wire [(dw+(dw/8))-1:0] do_a_wire;
|
wire [(dw+par_w)-1:0] do_a_wire;
|
wire [(dw/8)-1:0] di_p;
|
wire [par_w-1:0] di_p;
|
wire [(dw/8)-1:0] do_p;
|
wire [par_w-1:0] do_p;
|
wire [(dw/8)-1:0] parity_err;
|
wire [par_w-1:0] parity_err;
|
`else
|
`else
|
wire [dw-1:0] do_a_wire;
|
wire [dw-1:0] do_a_wire;
|
`endif
|
`endif
|
|
|
// Function to access GPRs (for use by Verilator). No need to hide this one
|
// Function to access GPRs (for use by Verilator). No need to hide this one
|
// from the simulator, since it has an input (as required by IEEE 1364-2001).
|
// from the simulator, since it has an input (as required by IEEE 1364-2001).
|
function [31:0] get_gpr;
|
function [31:0] get_gpr;
|
// verilator public
|
// verilator public
|
input [aw-1:0] gpr_no;
|
input [aw-1:0] gpr_no;
|
reg [(dw+(dw/8))-1:0] gpr_temp;
|
|
begin
|
|
`ifdef OR1200_RAM_PARITY
|
`ifdef OR1200_RAM_PARITY
|
|
reg [(dw+par_w)-1:0] gpr_temp;
|
|
begin
|
gpr_temp = mem[gpr_no];
|
gpr_temp = mem[gpr_no];
|
get_gpr = gpr_temp[31:0];
|
get_gpr = gpr_temp[31:0];
|
|
end
|
`else
|
`else
|
|
|
get_gpr = mem[gpr_no];
|
get_gpr = mem[gpr_no];
|
`endif
|
`endif
|
end
|
|
endfunction // get_gpr
|
endfunction // get_gpr
|
|
|
task set_gpr;
|
task set_gpr;
|
// verilator public
|
// verilator public
|
input [aw-1:0] gpr_no;
|
input [aw-1:0] gpr_no;
|
Line 149... |
Line 154... |
endtask // get_gpr
|
endtask // get_gpr
|
|
|
`ifdef OR1200_RAM_PARITY
|
`ifdef OR1200_RAM_PARITY
|
genvar i;
|
genvar i;
|
generate
|
generate
|
for (i=0;i<(dw/8);i=i+1) begin: paritygen
|
for (i=0;i<par_w;i=i+1) begin: paritygen
|
or1200_parity_gen pgen(.d_i(di_b[(i*8)+7:(i*8)]), .p_o(di_p[i]));
|
or1200_parity_gen pgen(.d_i(di_b[(i*8)+7:(i*8)]), .p_o(di_p[i]));
|
or1200_parity_chk pchk(.d_i(do_a_wire[(i*8)+7:(i*8)]),
|
or1200_parity_chk pchk(.d_i(do_a_wire[(i*8)+7:(i*8)]),
|
.p_i(do_p[i]), .err_o(parity_err[i]));
|
.p_i(do_p[i]), .err_o(parity_err[i]));
|
end
|
end
|
endgenerate
|
endgenerate
|
|
|
// Extract parity bits of data out
|
// Extract parity bits of data out
|
assign do_p = do_a_wire[(dw+(dw/8))-1:dw];
|
assign do_p = do_a_wire[(dw+par_w)-1:dw];
|
|
|
|
reg ce_a_r;
|
|
always @(posedge clk_a)
|
|
if (rst)
|
|
ce_a_r <= 0;
|
|
else
|
|
ce_a_r <= ce_a;
|
|
|
// Indicate error
|
// Indicate error
|
assign p_err = (|parity_err);
|
assign p_err = (|parity_err) & ce_a_r;
|
|
|
// Inject a parity error. Can specify GPR number to affect,
|
// Inject a parity error. Can specify GPR number to affect,
|
// and which parity or data bit to switch.
|
// and which parity or data bit to switch.
|
task gen_parity_err;
|
task gen_parity_err;
|
input [aw-1:0] gpr_no;
|
input [aw-1:0] gpr_no;
|
input [31:0] parity_bit_no;
|
input [31:0] parity_bit_no;
|
input [31:0] data_bit_no;
|
input [31:0] data_bit_no;
|
reg [(dw+(dw/8))-1:0] do_temp;
|
reg [(dw+par_w)-1:0] do_temp;
|
begin
|
begin
|
do_temp = mem[gpr_no];
|
do_temp = mem[gpr_no];
|
// Switch parity bit
|
// Switch parity bit
|
if (parity_bit_no > 0)
|
if (parity_bit_no >= 0 && parity_bit_no < par_w)
|
do_temp[dw+(parity_bit_no-1)] = ~do_temp[dw+(parity_bit_no-1)];
|
do_temp[dw+parity_bit_no] = ~do_temp[dw+parity_bit_no];
|
// Switch data bit
|
// Switch data bit
|
if (data_bit_no > 0 && data_bit_no <= dw)
|
if (data_bit_no >= 0 && data_bit_no < dw)
|
do_temp[data_bit_no-1] = ~do_temp[data_bit_no-1];
|
do_temp[data_bit_no] = ~do_temp[data_bit_no];
|
// Write word back
|
// Write word back
|
mem[gpr_no] = do_temp;
|
mem[gpr_no] = do_temp;
|
end
|
end
|
endtask // gen_parity_err
|
endtask // gen_parity_err
|
|
|
|
|
`endif
|
`endif
|
|
|
//
|
//
|
// Data output drivers
|
// Data output drivers
|
//
|
//
|