Line 64... |
Line 64... |
// RAM BIST
|
// RAM BIST
|
mbist_si_i, mbist_so_o, mbist_ctrl_i,
|
mbist_si_i, mbist_so_o, mbist_ctrl_i,
|
`endif
|
`endif
|
// Generic synchronous single-port RAM interface
|
// Generic synchronous single-port RAM interface
|
clk, ce, we, addr, di, doq
|
clk, ce, we, addr, di, doq
|
|
`ifdef OR1200_RAM_PARITY
|
|
, p_err
|
|
`endif
|
);
|
);
|
|
|
//
|
//
|
// Default address and data buses width
|
// Default address and data buses width
|
//
|
//
|
parameter aw = 10;
|
parameter aw = 10;
|
parameter dw = 32;
|
parameter dw = 32;
|
|
|
|
parameter bw = 8;
|
|
|
|
|
`ifdef OR1200_BIST
|
`ifdef OR1200_BIST
|
//
|
//
|
// RAM BIST
|
// RAM BIST
|
//
|
//
|
input mbist_si_i;
|
input mbist_si_i;
|
Line 90... |
Line 96... |
input ce; // Chip enable input
|
input ce; // Chip enable input
|
input [3:0] we; // Write enable input
|
input [3:0] we; // Write enable input
|
input [aw-1:0] addr; // address bus inputs
|
input [aw-1:0] addr; // address bus inputs
|
input [dw-1:0] di; // input data bus
|
input [dw-1:0] di; // input data bus
|
output [dw-1:0] doq; // output data bus
|
output [dw-1:0] doq; // output data bus
|
|
`ifdef OR1200_RAM_PARITY
|
|
output p_err; // parity error indicator
|
|
`endif
|
|
|
//
|
//
|
// Internal wires and registers
|
// Internal wires and registers
|
//
|
//
|
|
|
Line 102... |
Line 111... |
//
|
//
|
|
|
//
|
//
|
// Generic RAM's registers and wires
|
// Generic RAM's registers and wires
|
//
|
//
|
`ifdef OR1200_GENERIC
|
`ifdef OR1200_RAM_PARITY
|
reg [7:0] mem0 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [bw:0] mem0 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [7:0] mem1 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [bw:0] mem1 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [7:0] mem2 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [bw:0] mem2 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [7:0] mem3 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [bw:0] mem3 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
`else
|
`else
|
reg [7:0] mem0 [(1<<aw)-1:0];
|
reg [bw-1:0] mem0 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [7:0] mem1 [(1<<aw)-1:0];
|
reg [bw-1:0] mem1 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [7:0] mem2 [(1<<aw)-1:0];
|
reg [bw-1:0] mem2 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
reg [7:0] mem3 [(1<<aw)-1:0];
|
reg [bw-1:0] mem3 [(1<<aw)-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
|
`endif
|
`endif
|
reg [aw-1:0] addr_reg; // RAM address register
|
reg [aw-1:0] addr_reg; // RAM address register
|
|
|
|
`ifdef OR1200_RAM_PARITY
|
|
wire [(dw+(dw/8))-1:0] doq_wire;
|
|
wire [bw:0] doq0_wire;
|
|
wire [bw:0] doq1_wire;
|
|
wire [bw:0] doq2_wire;
|
|
wire [bw:0] doq3_wire;
|
|
wire [(dw/8)-1:0] di_p;
|
|
wire [(dw/8)-1:0] do_p;
|
|
wire [(dw/8)-1:0] parity_err;
|
|
`else
|
|
wire [dw-1:0] doq_wire;
|
|
`endif
|
|
|
|
`ifdef OR1200_RAM_PARITY
|
|
genvar i;
|
|
generate
|
|
for (i=0;i<(dw/8);i=i+1) begin: paritygen
|
|
or1200_parity_gen pgen(.d_i(di[(i*8)+7:(i*8)]), .p_o(di_p[i]));
|
|
or1200_parity_chk pchk(.d_i(doq_wire[(i*8)+7:(i*8)]),
|
|
.p_i(do_p[i]), .err_o(parity_err[i]));
|
|
end
|
|
endgenerate
|
|
|
|
// Extract parity bits of data out
|
|
assign do_p = doq_wire[(dw+(dw/8))-1:dw];
|
|
|
|
// Indicate error
|
|
assign p_err = (|parity_err);
|
|
|
|
// Inject a parity error. Can specify GPR number to affect,
|
|
// and which parity or data bit to switch.
|
|
task gen_parity_err;
|
|
input [aw-1:0] gpr_no;
|
|
input [31:0] parity_bit_no;
|
|
input [31:0] data_bit_no;
|
|
reg [(dw+(dw/8))-1:0] do_temp;
|
|
begin
|
|
// TODO
|
|
/*
|
|
do_temp = mem[gpr_no];
|
|
// Switch parity bit
|
|
if (parity_bit_no > 0 && parity_bit_no <= (dw/8))
|
|
do_temp[dw+(parity_bit_no-1)] = ~do_temp[dw+(parity_bit_no-1)];
|
|
// Switch data bit
|
|
if (data_bit_no > 0 && data_bit_no <= dw)
|
|
do_temp[data_bit_no-1] = ~do_temp[data_bit_no-1];
|
|
// Write word back
|
|
mem[gpr_no] = do_temp;
|
|
*/
|
|
end
|
|
endtask // gen_parity_err
|
|
`endif
|
|
|
//
|
//
|
// Data output drivers
|
// Data output drivers
|
//
|
//
|
assign doq = {mem0[addr_reg], mem1[addr_reg], mem2[addr_reg], mem3[addr_reg]};
|
`ifdef OR1200_RAM_PARITY
|
|
assign doq0_wire = mem0[addr_reg];
|
|
assign doq1_wire = mem1[addr_reg];
|
|
assign doq2_wire = mem2[addr_reg];
|
|
assign doq3_wire = mem3[addr_reg];
|
|
|
|
assign doq_wire = {// Parity bits
|
|
doq0_wire[bw],doq1_wire[bw],doq2_wire[bw],doq3_wire[bw],
|
|
// Data bytes
|
|
doq0_wire[bw-1:0],doq1_wire[bw-1:0],
|
|
doq2_wire[bw-1:0],doq3_wire[bw-1:0]};
|
|
`else
|
|
assign doq_wire = {mem0[addr_reg], mem1[addr_reg], mem2[addr_reg], mem3[addr_reg]};
|
|
`endif
|
|
assign doq = doq_wire[dw-1:0];
|
|
|
|
|
//
|
//
|
// RAM read address register
|
// RAM read address register
|
//
|
//
|
always @(posedge clk)
|
always @(posedge clk)
|
Line 132... |
Line 209... |
//
|
//
|
// RAM write - big endian selection
|
// RAM write - big endian selection
|
//
|
//
|
always @(posedge clk)
|
always @(posedge clk)
|
if (ce) begin
|
if (ce) begin
|
|
`ifdef OR1200_RAM_PARITY
|
if (we[3])
|
if (we[3])
|
mem0[addr] <= di[31:24];
|
mem0[addr] <= {di_p[3],di[(bw*3)+(bw-1):(bw*3)]};
|
if (we[2])
|
if (we[2])
|
mem1[addr] <= di[23:16];
|
mem1[addr] <= {di_p[2],di[(bw*2)+(bw-1):(bw*2)]};
|
if (we[1])
|
if (we[1])
|
mem2[addr] <= di[15:08];
|
mem2[addr] <= {di_p[1],di[(bw*1)+(bw-1):(bw*1)]};
|
if (we[0])
|
if (we[0])
|
mem3[addr] <= di[07:00];
|
mem3[addr] <= {di_p[0],di[(bw*0)+(bw-1):(bw*0)]};
|
|
`else
|
|
if (we[3])
|
|
mem0[addr] <= di[(bw*3)+(bw-1):(bw*3)];
|
|
if (we[2])
|
|
mem1[addr] <= di[(bw*2)+(bw-1):(bw*2)];
|
|
if (we[1])
|
|
mem2[addr] <= di[(bw*1)+(bw-1):(bw*1)];
|
|
if (we[0])
|
|
mem3[addr] <= di[(bw*0)+(bw-1):(bw*0)];
|
|
`endif
|
end
|
end
|
|
|
endmodule // or1200_spram
|
endmodule // or1200_spram
|
|
|
No newline at end of file
|
No newline at end of file
|