Line 530... |
Line 530... |
output reg q;
|
output reg q;
|
output clk, rst;
|
output clk, rst;
|
reg dff;
|
reg dff;
|
always @ (posedge clk or posedge rst)
|
always @ (posedge clk or posedge rst)
|
if (rst)
|
if (rst)
|
{dff,q} <= 2'b00;
|
{q,dff} <= 2'b00;
|
else
|
else
|
{dff,q} <= {d,dff};
|
{q,dff} <= {dff,d};
|
endmodule
|
endmodule
|
module vl_cdc ( start_pl, take_it_pl, take_it_grant_pl, got_it_pl, clk_src, rst_src, clk_dst, rst_dst);
|
module vl_cdc ( start_pl, take_it_pl, take_it_grant_pl, got_it_pl, clk_src, rst_src, clk_dst, rst_dst);
|
input start_pl;
|
input start_pl;
|
output take_it_pl;
|
output take_it_pl;
|
input take_it_grant_pl; // note: connect to take_it_pl to generate automatic ack
|
input take_it_grant_pl; // note: connect to take_it_pl to generate automatic ack
|
Line 555... |
Line 555... |
.d(take_it_tg),
|
.d(take_it_tg),
|
.q(take_it_tg_sync),
|
.q(take_it_tg_sync),
|
.clk(clk_dst),
|
.clk(clk_dst),
|
.rst(rst_dst));
|
.rst(rst_dst));
|
vl_toggle2pulse t2p0 (
|
vl_toggle2pulse t2p0 (
|
.d(take_it_sync),
|
.d(take_it_tg_sync),
|
.pl(take_it_pl),
|
.pl(take_it_pl),
|
.clk(clk_dst),
|
.clk(clk_dst),
|
.rst(rst_dst));
|
.rst(rst_dst));
|
// dst -> src
|
// dst -> src
|
vl_pulse2toggle p2t1 (
|
vl_pulse2toggle p2t1 (
|
Line 571... |
Line 571... |
.d(got_it_tg),
|
.d(got_it_tg),
|
.q(got_it_tg_sync),
|
.q(got_it_tg_sync),
|
.clk(clk_src),
|
.clk(clk_src),
|
.rst(rst_src));
|
.rst(rst_src));
|
vl_toggle2pulse t2p1 (
|
vl_toggle2pulse t2p1 (
|
.d(take_it_grant_tg_sync),
|
.d(got_it_tg_sync),
|
.pl(got_it_pl),
|
.pl(got_it_pl),
|
.clk(clk_src),
|
.clk(clk_src),
|
.rst(rst_src));
|
.rst(rst_src));
|
endmodule
|
endmodule
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
Line 1395... |
Line 1395... |
// Single port RAM
|
// Single port RAM
|
module vl_ram ( d, adr, we, q, clk);
|
module vl_ram ( d, adr, we, q, clk);
|
parameter data_width = 32;
|
parameter data_width = 32;
|
parameter addr_width = 8;
|
parameter addr_width = 8;
|
parameter mem_size = 1<<addr_width;
|
parameter mem_size = 1<<addr_width;
|
|
parameter debug = 0;
|
input [(data_width-1):0] d;
|
input [(data_width-1):0] d;
|
input [(addr_width-1):0] adr;
|
input [(addr_width-1):0] adr;
|
input we;
|
input we;
|
output reg [(data_width-1):0] q;
|
output reg [(data_width-1):0] q;
|
input clk;
|
input clk;
|
reg [data_width-1:0] ram [mem_size-1:0];
|
reg [data_width-1:0] ram [mem_size-1:0];
|
parameter init = 0;
|
parameter memory_init = 0;
|
parameter memory_file = "vl_ram.vmem";
|
parameter memory_file = "vl_ram.vmem";
|
generate if (init) begin : init_mem
|
generate
|
|
if (memory_init == 1) begin : init_mem
|
initial
|
initial
|
begin
|
|
$readmemh(memory_file, ram);
|
$readmemh(memory_file, ram);
|
|
end else if (memory_init == 2) begin : init_zero
|
|
integer k;
|
|
initial
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
end
|
end
|
|
endgenerate
|
|
generate
|
|
if (debug==1) begin : debug_we
|
|
always @ (posedge clk)
|
|
if (we)
|
|
$display ("Value %h written at address %h : time %t", d, adr, $time);
|
end
|
end
|
endgenerate
|
endgenerate
|
always @ (posedge clk)
|
always @ (posedge clk)
|
begin
|
begin
|
if (we)
|
if (we)
|
Line 1437... |
Line 1449... |
reg [data_width-1:0] ram [mem_size-1:0];
|
reg [data_width-1:0] ram [mem_size-1:0];
|
wire [data_width/8-1:0] cke;
|
wire [data_width/8-1:0] cke;
|
`endif
|
`endif
|
parameter memory_init = 0;
|
parameter memory_init = 0;
|
parameter memory_file = "vl_ram.vmem";
|
parameter memory_file = "vl_ram.vmem";
|
generate if (memory_init) begin : init_mem
|
generate
|
|
if (memory_init == 1) begin : init_mem
|
initial
|
initial
|
begin
|
|
$readmemh(memory_file, ram);
|
$readmemh(memory_file, ram);
|
end
|
end else if (memory_init == 2) begin : init_zero
|
|
integer k;
|
|
initial
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
end
|
end
|
endgenerate
|
endgenerate
|
`ifdef SYSTEMVERILOG
|
`ifdef SYSTEMVERILOG
|
always_ff@(posedge clk)
|
always_ff@(posedge clk)
|
begin
|
begin
|
Line 1494... |
Line 1510... |
input [(addr_width-1):0] adr_b;
|
input [(addr_width-1):0] adr_b;
|
input we_a;
|
input we_a;
|
output [(data_width-1):0] q_b;
|
output [(data_width-1):0] q_b;
|
input clk_a, clk_b;
|
input clk_a, clk_b;
|
reg [(addr_width-1):0] adr_b_reg;
|
reg [(addr_width-1):0] adr_b_reg;
|
reg [data_width-1:0] ram [mem_szie-1:0] ;
|
reg [data_width-1:0] ram [mem_size-1:0] ;
|
parameter init = 0;
|
parameter memory_init = 0;
|
parameter memory_file = "vl_ram.vmem";
|
parameter memory_file = "vl_ram.vmem";
|
generate if (init) begin : init_mem
|
parameter debug = 0;
|
|
generate
|
|
if (memory_init == 1) begin : init_mem
|
initial
|
initial
|
begin
|
|
$readmemh(memory_file, ram);
|
$readmemh(memory_file, ram);
|
|
end else if (memory_init == 2) begin : init_zero
|
|
integer k;
|
|
initial
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
end
|
end
|
|
endgenerate
|
|
generate
|
|
if (debug==1) begin : debug_we
|
|
always @ (posedge clk_a)
|
|
if (we_a)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
|
end
|
end
|
endgenerate
|
endgenerate
|
always @ (posedge clk_a)
|
always @ (posedge clk_a)
|
if (we_a)
|
if (we_a)
|
ram[adr_a] <= d_a;
|
ram[adr_a] <= d_a;
|
Line 1524... |
Line 1552... |
output [(data_width-1):0] q_b;
|
output [(data_width-1):0] q_b;
|
output reg [(data_width-1):0] q_a;
|
output reg [(data_width-1):0] q_a;
|
input clk_a, clk_b;
|
input clk_a, clk_b;
|
reg [(data_width-1):0] q_b;
|
reg [(data_width-1):0] q_b;
|
reg [data_width-1:0] ram [mem_szie-1:0] ;
|
reg [data_width-1:0] ram [mem_szie-1:0] ;
|
parameter init = 0;
|
parameter memory_init = 0;
|
parameter memory_file = "vl_ram.vmem";
|
parameter memory_file = "vl_ram.vmem";
|
generate if (init) begin : init_mem
|
parameter debug = 0;
|
|
generate
|
|
if (memory_init == 1) begin : init_mem
|
initial
|
initial
|
begin
|
|
$readmemh(memory_file, ram);
|
$readmemh(memory_file, ram);
|
|
end else if (memory_init == 2) begin : init_zero
|
|
integer k;
|
|
initial
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
end
|
end
|
|
endgenerate
|
|
generate
|
|
if (debug==1) begin : debug_we
|
|
always @ (posedge clk_a)
|
|
if (we_a)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
|
end
|
end
|
endgenerate
|
endgenerate
|
always @ (posedge clk_a)
|
always @ (posedge clk_a)
|
begin
|
begin
|
q_a <= ram[adr_a];
|
q_a <= ram[adr_a];
|
Line 1542... |
Line 1582... |
ram[adr_a] <= d_a;
|
ram[adr_a] <= d_a;
|
end
|
end
|
always @ (posedge clk_b)
|
always @ (posedge clk_b)
|
q_b <= ram[adr_b];
|
q_b <= ram[adr_b];
|
endmodule
|
endmodule
|
|
module vl_dpram_1r2w ( d_a, q_a, adr_a, we_a, clk_a, d_b, adr_b, we_b, clk_b );
|
|
parameter data_width = 32;
|
|
parameter addr_width = 8;
|
|
parameter mem_size = 1<<addr_width;
|
|
input [(data_width-1):0] d_a;
|
|
input [(addr_width-1):0] adr_a;
|
|
input [(addr_width-1):0] adr_b;
|
|
input we_a;
|
|
input [(data_width-1):0] d_b;
|
|
output reg [(data_width-1):0] q_a;
|
|
input we_b;
|
|
input clk_a, clk_b;
|
|
reg [(data_width-1):0] q_b;
|
|
reg [data_width-1:0] ram [mem_size-1:0] ;
|
|
parameter memory_init = 0;
|
|
parameter memory_file = "vl_ram.vmem";
|
|
parameter debug = 0;
|
|
generate
|
|
if (memory_init == 1) begin : init_mem
|
|
initial
|
|
$readmemh(memory_file, ram);
|
|
end else if (memory_init == 2) begin : init_zero
|
|
integer k;
|
|
initial
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
|
end
|
|
endgenerate
|
|
generate
|
|
if (debug==1) begin : debug_we
|
|
always @ (posedge clk_a)
|
|
if (we_a)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
|
|
always @ (posedge clk_b)
|
|
if (we_b)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
|
|
end
|
|
endgenerate
|
|
always @ (posedge clk_a)
|
|
begin
|
|
q_a <= ram[adr_a];
|
|
if (we_a)
|
|
ram[adr_a] <= d_a;
|
|
end
|
|
always @ (posedge clk_b)
|
|
begin
|
|
if (we_b)
|
|
ram[adr_b] <= d_b;
|
|
end
|
|
endmodule
|
module vl_dpram_2r2w ( d_a, q_a, adr_a, we_a, clk_a, d_b, q_b, adr_b, we_b, clk_b );
|
module vl_dpram_2r2w ( d_a, q_a, adr_a, we_a, clk_a, d_b, q_b, adr_b, we_b, clk_b );
|
parameter data_width = 32;
|
parameter data_width = 32;
|
parameter addr_width = 8;
|
parameter addr_width = 8;
|
parameter mem_size = 1<<addr_width;
|
parameter mem_size = 1<<addr_width;
|
input [(data_width-1):0] d_a;
|
input [(data_width-1):0] d_a;
|
Line 1557... |
Line 1647... |
output reg [(data_width-1):0] q_a;
|
output reg [(data_width-1):0] q_a;
|
input we_b;
|
input we_b;
|
input clk_a, clk_b;
|
input clk_a, clk_b;
|
reg [(data_width-1):0] q_b;
|
reg [(data_width-1):0] q_b;
|
reg [data_width-1:0] ram [mem_size-1:0] ;
|
reg [data_width-1:0] ram [mem_size-1:0] ;
|
parameter init = 0;
|
parameter memory_init = 0;
|
parameter memory_file = "vl_ram.vmem";
|
parameter memory_file = "vl_ram.vmem";
|
generate if (init) begin : init_mem
|
parameter debug = 0;
|
|
generate
|
|
if (memory_init) begin : init_mem
|
initial
|
initial
|
begin
|
|
$readmemh(memory_file, ram);
|
$readmemh(memory_file, ram);
|
|
end else if (memory_init == 2) begin : init_zero
|
|
integer k;
|
|
initial
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
end
|
end
|
|
endgenerate
|
|
generate
|
|
if (debug==1) begin : debug_we
|
|
always @ (posedge clk_a)
|
|
if (we_a)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
|
|
always @ (posedge clk_b)
|
|
if (we_b)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
|
end
|
end
|
endgenerate
|
endgenerate
|
always @ (posedge clk_a)
|
always @ (posedge clk_a)
|
begin
|
begin
|
q_a <= ram[adr_a];
|
q_a <= ram[adr_a];
|
Line 1586... |
Line 1691... |
parameter a_addr_width = 8;
|
parameter a_addr_width = 8;
|
parameter b_data_width = 64; //a_data_width;
|
parameter b_data_width = 64; //a_data_width;
|
localparam b_addr_width = a_data_width * a_addr_width / b_data_width;
|
localparam b_addr_width = a_data_width * a_addr_width / b_data_width;
|
localparam ratio = (a_addr_width>b_addr_width) ? (a_addr_width/b_addr_width) : (b_addr_width/a_addr_width);
|
localparam ratio = (a_addr_width>b_addr_width) ? (a_addr_width/b_addr_width) : (b_addr_width/a_addr_width);
|
parameter mem_size = (a_addr_width>b_addr_width) ? (1<<b_addr_width) : (1<<a_addr_width);
|
parameter mem_size = (a_addr_width>b_addr_width) ? (1<<b_addr_width) : (1<<a_addr_width);
|
parameter init = 0;
|
parameter memory_init = 0;
|
parameter memory_file = "vl_ram.vmem";
|
parameter memory_file = "vl_ram.vmem";
|
|
parameter debug = 0;
|
input [(a_data_width-1):0] d_a;
|
input [(a_data_width-1):0] d_a;
|
input [(a_addr_width-1):0] adr_a;
|
input [(a_addr_width-1):0] adr_a;
|
input [(a_data_width/8-1):0] be_a;
|
input [(a_data_width/8-1):0] be_a;
|
input we_a;
|
input we_a;
|
output reg [(a_data_width-1):0] q_a;
|
output reg [(a_data_width-1):0] q_a;
|
Line 1599... |
Line 1705... |
input [(b_addr_width-1):0] adr_b;
|
input [(b_addr_width-1):0] adr_b;
|
input [(b_data_width/8-1):0] be_b;
|
input [(b_data_width/8-1):0] be_b;
|
input we_b;
|
input we_b;
|
output reg [(b_data_width-1):0] q_b;
|
output reg [(b_data_width-1):0] q_b;
|
input clk_a, clk_b;
|
input clk_a, clk_b;
|
|
generate
|
|
if (debug==1) begin : debug_we
|
|
always @ (posedge clk_a)
|
|
if (we_a)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_a, adr_a, $time);
|
|
always @ (posedge clk_b)
|
|
if (we_b)
|
|
$display ("Debug: Value %h written at address %h : time %t", d_b, adr_b, $time);
|
|
end
|
|
endgenerate
|
`ifdef SYSTEMVERILOG
|
`ifdef SYSTEMVERILOG
|
// use a multi-dimensional packed array
|
// use a multi-dimensional packed array
|
//to model individual bytes within the word
|
//to model individual bytes within the word
|
generate
|
generate
|
if (a_data_width==32 & b_data_width==32) begin : dpram_3232
|
if (a_data_width==32 & b_data_width==32) begin : dpram_3232
|
logic [0:3][7:0] ram [0:mem_size-1] ;
|
logic [0:3][7:0] ram [0:mem_size-1] ;
|
initial
|
initial
|
if (init)
|
if (memory_init==1)
|
$readmemh(memory_file, ram);
|
$readmemh(memory_file, ram);
|
|
integer k;
|
|
initial
|
|
if (memory_init==2)
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
always_ff@(posedge clk_a)
|
always_ff@(posedge clk_a)
|
begin
|
begin
|
if(we_a) begin
|
if(we_a) begin
|
if(be_a[3]) ram[adr_a][3] <= d_a[31:24];
|
if(be_a[3]) ram[adr_a][0] <= d_a[31:24];
|
if(be_a[2]) ram[adr_a][2] <= d_a[23:16];
|
if(be_a[2]) ram[adr_a][1] <= d_a[23:16];
|
if(be_a[1]) ram[adr_a][1] <= d_a[15:8];
|
if(be_a[1]) ram[adr_a][2] <= d_a[15:8];
|
if(be_a[0]) ram[adr_a][0] <= d_a[7:0];
|
if(be_a[0]) ram[adr_a][3] <= d_a[7:0];
|
end
|
end
|
end
|
end
|
always@(posedge clk_a)
|
always@(posedge clk_a)
|
q_a = ram[adr_a];
|
q_a = ram[adr_a];
|
always_ff@(posedge clk_b)
|
always_ff@(posedge clk_b)
|
begin
|
begin
|
if(we_b) begin
|
if(we_b) begin
|
if(be_b[3]) ram[adr_b][3] <= d_b[31:24];
|
if(be_b[3]) ram[adr_b][0] <= d_b[31:24];
|
if(be_b[2]) ram[adr_b][2] <= d_b[23:16];
|
if(be_b[2]) ram[adr_b][1] <= d_b[23:16];
|
if(be_b[1]) ram[adr_b][1] <= d_b[15:8];
|
if(be_b[1]) ram[adr_b][2] <= d_b[15:8];
|
if(be_b[0]) ram[adr_b][0] <= d_b[7:0];
|
if(be_b[0]) ram[adr_b][3] <= d_b[7:0];
|
end
|
end
|
end
|
end
|
always@(posedge clk_b)
|
always@(posedge clk_b)
|
q_b = ram[adr_b];
|
q_b = ram[adr_b];
|
end
|
end
|
endgenerate
|
endgenerate
|
generate
|
generate
|
if (a_data_width==64 & b_data_width==64) begin : dpram_6464
|
if (a_data_width==64 & b_data_width==64) begin : dpram_6464
|
logic [0:7][7:0] ram [0:mem_size-1] ;
|
logic [0:7][7:0] ram [0:mem_size-1] ;
|
initial
|
initial
|
if (init)
|
if (memory_init==1)
|
$readmemh(memory_file, ram);
|
$readmemh(memory_file, ram);
|
|
integer k;
|
|
initial
|
|
if (memory_init==2)
|
|
for (k = 0; k < mem_size; k = k + 1)
|
|
ram[k] = 0;
|
always_ff@(posedge clk_a)
|
always_ff@(posedge clk_a)
|
begin
|
begin
|
if(we_a) begin
|
if(we_a) begin
|
if(be_a[7]) ram[adr_a][7] <= d_a[63:56];
|
if(be_a[7]) ram[adr_a][7] <= d_a[63:56];
|
if(be_a[6]) ram[adr_a][6] <= d_a[55:48];
|
if(be_a[6]) ram[adr_a][6] <= d_a[55:48];
|
Line 1673... |
Line 1799... |
end
|
end
|
endgenerate
|
endgenerate
|
generate
|
generate
|
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
|
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
|
logic [31:0] temp;
|
logic [31:0] temp;
|
vl_dpram_be_2r2w # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(init), .memory_file(memory_file))
|
vl_dpram_be_2r2w # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(memory_init), .memory_file(memory_file))
|
dpram6464 (
|
dpram6464 (
|
.d_a(d_a),
|
.d_a(d_a),
|
.q_a(q_a),
|
.q_a(q_a),
|
.adr_a(adr_a),
|
.adr_a(adr_a),
|
.be_a(be_a),
|
.be_a(be_a),
|
Line 1688... |
Line 1814... |
.adr_b(adr_b),
|
.adr_b(adr_b),
|
.be_b({be_b,be_b} & {{2{adr_b[0]}},{2{!adr_b[0]}}}),
|
.be_b({be_b,be_b} & {{2{adr_b[0]}},{2{!adr_b[0]}}}),
|
.we_b(we_b),
|
.we_b(we_b),
|
.clk_b(clk_b)
|
.clk_b(clk_b)
|
);
|
);
|
always_comb
|
always @ (adr_b[0] or temp)
|
if (adr_b[0])
|
if (adr_b[0])
|
q_b = temp[31:16];
|
q_b = temp[31:16];
|
else
|
else
|
q_b = temp[15:0];
|
q_b = temp[15:0];
|
end
|
end
|
endgenerate
|
endgenerate
|
generate
|
generate
|
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
|
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
|
logic [63:0] temp;
|
logic [63:0] temp;
|
vl_dpram_be_2r2w # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(init), .memory_file(memory_file))
|
vl_dpram_be_2r2w # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(memory_init), .memory_file(memory_file))
|
dpram6464 (
|
dpram6464 (
|
.d_a({d_a,d_a}),
|
.d_a({d_a,d_a}),
|
.q_a(temp),
|
.q_a(temp),
|
.adr_a(adr_a[a_addr_width-1:1]),
|
.adr_a(adr_a[a_addr_width-1:1]),
|
.be_a({be_a,be_a} & {{4{adr_a[0]}},{4{!adr_a[0]}}}),
|
.be_a({be_a,be_a} & {{4{adr_a[0]}},{4{!adr_a[0]}}}),
|
Line 1713... |
Line 1839... |
.adr_b(adr_b),
|
.adr_b(adr_b),
|
.be_b(be_b),
|
.be_b(be_b),
|
.we_b(we_b),
|
.we_b(we_b),
|
.clk_b(clk_b)
|
.clk_b(clk_b)
|
);
|
);
|
always_comb
|
always @ (adr_a[0] or temp)
|
if (adr_a[0])
|
if (adr_a[0])
|
q_a = temp[63:32];
|
q_a = temp[63:32];
|
else
|
else
|
q_a = temp[31:0];
|
q_a = temp[31:0];
|
end
|
end
|
Line 2762... |
Line 2888... |
module vl_wb_b4_ram_be (
|
module vl_wb_b4_ram_be (
|
wb_dat_i, wb_adr_i, wb_sel_i, wb_we_i, wb_stb_i, wb_cyc_i,
|
wb_dat_i, wb_adr_i, wb_sel_i, wb_we_i, wb_stb_i, wb_cyc_i,
|
wb_dat_o, wb_stall_o, wb_ack_o, wb_clk, wb_rst);
|
wb_dat_o, wb_stall_o, wb_ack_o, wb_clk, wb_rst);
|
parameter dat_width = 32;
|
parameter dat_width = 32;
|
parameter adr_width = 8;
|
parameter adr_width = 8;
|
|
parameter mem_size = 1<<adr_width;
|
|
parameter memory_init = 0;
|
|
parameter memory_file = "vl_ram.v";
|
|
parameter debug = 0;
|
input [dat_width-1:0] wb_dat_i;
|
input [dat_width-1:0] wb_dat_i;
|
input [adr_width-1:0] wb_adr_i;
|
input [adr_width-1:0] wb_adr_i;
|
input [dat_width/8-1:0] wb_sel_i;
|
input [dat_width/8-1:0] wb_sel_i;
|
input wb_we_i, wb_stb_i, wb_cyc_i;
|
input wb_we_i, wb_stb_i, wb_cyc_i;
|
output [dat_width-1:0] wb_dat_o;
|
output [dat_width-1:0] wb_dat_o;
|
reg [dat_width-1:0] wb_dat_o;
|
|
output wb_stall_o;
|
output wb_stall_o;
|
output wb_ack_o;
|
output wb_ack_o;
|
reg wb_ack_o;
|
reg wb_ack_o;
|
input wb_clk, wb_rst;
|
input wb_clk, wb_rst;
|
wire [dat_width/8-1:0] cke;
|
wire [dat_width/8-1:0] cke;
|
generate
|
vl_ram_be # (
|
if (dat_width==32) begin
|
.data_width(dat_width),
|
reg [7:0] ram3 [1<<(adr_width-2)-1:0];
|
.addr_width(adr_width),
|
reg [7:0] ram2 [1<<(adr_width-2)-1:0];
|
.mem_size(mem_size),
|
reg [7:0] ram1 [1<<(adr_width-2)-1:0];
|
.memory_init(memory_init),
|
reg [7:0] ram0 [1<<(adr_width-2)-1:0];
|
.memory_file(memory_file))
|
assign cke = wb_sel_i & {(dat_width/8){wb_we_i}};
|
ram0(
|
always @ (posedge wb_clk)
|
.d(wb_dat_i),
|
begin
|
.adr(wb_adr_i),
|
if (cke[3]) ram3[wb_adr_i[adr_width-1:2]] <= wb_dat_i[31:24];
|
.be(wb_sel_i),
|
if (cke[2]) ram2[wb_adr_i[adr_width-1:2]] <= wb_dat_i[23:16];
|
.we(wb_we_i & wb_stb_i & wb_cyc_i),
|
if (cke[1]) ram1[wb_adr_i[adr_width-1:2]] <= wb_dat_i[15:8];
|
.q(wb_dat_o),
|
if (cke[0]) ram0[wb_adr_i[adr_width-1:2]] <= wb_dat_i[7:0];
|
.clk(wb_clk)
|
end
|
);
|
always @ (posedge wb_clk or posedge wb_rst)
|
|
begin
|
|
if (wb_rst)
|
|
wb_dat_o <= 32'h0;
|
|
else
|
|
wb_dat_o <= {ram3[wb_adr_i[adr_width-1:2]],ram2[wb_adr_i[adr_width-1:2]],ram1[wb_adr_i[adr_width-1:2]],ram0[wb_adr_i[adr_width-1:2]]};
|
|
end
|
|
end
|
|
endgenerate
|
|
always @ (posedge wb_clk or posedge wb_rst)
|
always @ (posedge wb_clk or posedge wb_rst)
|
if (wb_rst)
|
if (wb_rst)
|
wb_ack_o <= 1'b0;
|
wb_ack_o <= 1'b0;
|
else
|
else
|
wb_ack_o <= wb_stb_i & wb_cyc_i;
|
wb_ack_o <= wb_stb_i & wb_cyc_i;
|
Line 2903... |
Line 3023... |
wbm_dat_o, wbm_adr_o, wbm_sel_o, wbm_cti_o, wbm_bte_o, wbm_we_o, wbm_stb_o, wbm_cyc_o, wbm_dat_i, wbm_ack_i, wbm_stall_i, wbm_clk, wbm_rst
|
wbm_dat_o, wbm_adr_o, wbm_sel_o, wbm_cti_o, wbm_bte_o, wbm_we_o, wbm_stb_o, wbm_cyc_o, wbm_dat_i, wbm_ack_i, wbm_stall_i, wbm_clk, wbm_rst
|
);
|
);
|
parameter dw_s = 32;
|
parameter dw_s = 32;
|
parameter aw_s = 24;
|
parameter aw_s = 24;
|
parameter dw_m = dw_s;
|
parameter dw_m = dw_s;
|
parameter aw_m = dw_s * aw_s / dw_m;
|
localparam aw_m = dw_s * aw_s / dw_m;
|
parameter max_burst_width = 4;
|
parameter wbs_max_burst_width = 4;
|
parameter async = 1; // wbs_clk != wbm_clk
|
parameter async = 1; // wbs_clk != wbm_clk
|
parameter nr_of_ways = 1;
|
parameter nr_of_ways = 1;
|
parameter aw_offset = 4; // 4 => 16 words per cache line
|
parameter aw_offset = 4; // 4 => 16 words per cache line
|
parameter aw_slot = 10;
|
parameter aw_slot = 10;
|
|
parameter valid_mem = 0;
|
|
parameter debug = 0;
|
|
localparam aw_b_offset = aw_offset * dw_s / dw_m;
|
localparam aw_tag = aw_s - aw_slot - aw_offset;
|
localparam aw_tag = aw_s - aw_slot - aw_offset;
|
parameter wbm_burst_size = 4; // valid options 4,8,16
|
parameter wbm_burst_size = 4; // valid options 4,8,16
|
localparam bte = (wbm_burst_size==4) ? 2'b01 : (wbm_burst_size==8) ? 2'b10 : 2'b11;
|
localparam bte = (wbm_burst_size==4) ? 2'b01 : (wbm_burst_size==8) ? 2'b10 : 2'b11;
|
localparam wbm_burst_width = (wbm_burst_size==4) ? 2 : (wbm_burst_size==8) ? 3 : (wbm_burst_size==16) ? 4 : (wbm_burst_size==32) ? 5 : (wbm_burst_size==64) ? 6 : (wbm_burst_size==128) ? 7 : 8;
|
localparam wbm_burst_width = (wbm_burst_size==1) ? 0 : (wbm_burst_size==2) ? 1 : (wbm_burst_size==4) ? 2 : (wbm_burst_size==8) ? 3 : (wbm_burst_size==16) ? 4 : (wbm_burst_size==32) ? 5 : (wbm_burst_size==64) ? 6 : (wbm_burst_size==128) ? 7 : 8;
|
localparam nr_of_wbm_burst = ((1<<aw_offset)/wbm_burst_size) * dw_s / dw_m;
|
localparam nr_of_wbm_burst = ((1<<aw_offset)/wbm_burst_size) * dw_s / dw_m;
|
localparam nr_of_wbm_burst_width = (nr_of_wbm_burst==4) ? 2 : (nr_of_wbm_burst==8) ? 3 : (nr_of_wbm_burst==16) ? 4 : (nr_of_wbm_burst==32) ? 5 : (nr_of_wbm_burst==64) ? 6 : (nr_of_wbm_burst==128) ? 7 : 8;
|
localparam nr_of_wbm_burst_width = (nr_of_wbm_burst==1) ? 0 : (nr_of_wbm_burst==2) ? 1 : (nr_of_wbm_burst==4) ? 2 : (nr_of_wbm_burst==8) ? 3 : (nr_of_wbm_burst==16) ? 4 : (nr_of_wbm_burst==32) ? 5 : (nr_of_wbm_burst==64) ? 6 : (nr_of_wbm_burst==128) ? 7 : 8;
|
input [dw_s-1:0] wbs_dat_i;
|
input [dw_s-1:0] wbs_dat_i;
|
input [aw_s-1:0] wbs_adr_i; // dont include a1,a0
|
input [aw_s-1:0] wbs_adr_i; // dont include a1,a0
|
input [dw_s/8-1:0] wbs_sel_i;
|
input [dw_s/8-1:0] wbs_sel_i;
|
input [2:0] wbs_cti_i;
|
input [2:0] wbs_cti_i;
|
input [1:0] wbs_bte_i;
|
input [1:0] wbs_bte_i;
|
Line 2934... |
Line 3057... |
output wbm_stb_o, wbm_cyc_o, wbm_we_o;
|
output wbm_stb_o, wbm_cyc_o, wbm_we_o;
|
input [dw_m-1:0] wbm_dat_i;
|
input [dw_m-1:0] wbm_dat_i;
|
input wbm_ack_i;
|
input wbm_ack_i;
|
input wbm_stall_i;
|
input wbm_stall_i;
|
input wbm_clk, wbm_rst;
|
input wbm_clk, wbm_rst;
|
wire dirty, valid;
|
wire valid, dirty, hit;
|
wire [aw_tag-1:0] tag;
|
wire [aw_tag-1:0] tag;
|
wire tag_mem_we;
|
wire tag_mem_we;
|
wire [aw_tag-1:0] wbs_adr_tag;
|
wire [aw_tag-1:0] wbs_adr_tag;
|
wire [aw_slot-1:0] wbs_adr_slot;
|
wire [aw_slot-1:0] wbs_adr_slot;
|
wire [aw_offset-1:0] wbs_adr_word;
|
wire [aw_offset-1:0] wbs_adr_word;
|
Line 2952... |
Line 3075... |
// cdc
|
// cdc
|
wire done, mem_alert, mem_done;
|
wire done, mem_alert, mem_done;
|
// wbm side
|
// wbm side
|
reg [aw_m-1:0] wbm_radr;
|
reg [aw_m-1:0] wbm_radr;
|
reg [aw_m-1:0] wbm_wadr;
|
reg [aw_m-1:0] wbm_wadr;
|
wire [aw_slot+-1:0] wbm_adr;
|
wire [aw_slot-1:0] wbm_adr;
|
wire wbm_radr_cke, wbm_wadr_cke;
|
wire wbm_radr_cke, wbm_wadr_cke;
|
reg [1:0] phase;
|
reg [2:0] phase;
|
localparam wbm_wait = 2'b00;
|
// phase = {we,stb,cyc}
|
localparam wbm_rd = 2'b10;
|
localparam wbm_wait = 3'b000;
|
localparam wbm_wr = 2'b11;
|
localparam wbm_wr = 3'b111;
|
|
localparam wbm_wr_drain = 3'b101;
|
|
localparam wbm_rd = 3'b011;
|
|
localparam wbm_rd_drain = 3'b001;
|
assign {wbs_adr_tag, wbs_adr_slot, wbs_adr_word} = wbs_adr_i;
|
assign {wbs_adr_tag, wbs_adr_slot, wbs_adr_word} = wbs_adr_i;
|
assign eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
|
assign eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
|
vl_ram
|
generate
|
# ( .data_width(aw_tag), .addr_width(aw_slot))
|
if (valid_mem==0) begin : no_valid_mem
|
tag_mem ( .d(wbs_adr_slot), .adr(wbs_adr_tag), .we(done), .q(tag), .clk(wbs_clk));
|
assign valid = 1'b1;
|
assign valid = wbs_adr_tag == tag;
|
end else begin : valid_mem_inst
|
vl_wb_adr_inc # ( .adr_width(aw_s), .max_burst_width(max_burst_width)) adr_inc0 (
|
vl_dpram_1r1w
|
.cyc_i(wbs_cyc_i),
|
# ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
|
.stb_i(wbs_stb_i & (state==idle | (state==rw & valid))), // throttle depending on valid
|
valid_mem ( .d_a(1'b1), .adr_a(wbs_adr_slot), .we_a(mem_done), .clk_a(wbm_clk),
|
|
.q_b(valid), .adr_b(wbs_adr_slot), .clk_b(wbs_clk));
|
|
end
|
|
endgenerate
|
|
vl_dpram_1r1w
|
|
# ( .data_width(aw_tag), .addr_width(aw_slot), .memory_init(2), .debug(debug))
|
|
tag_mem ( .d_a(wbs_adr_tag), .adr_a(wbs_adr_slot), .we_a(mem_done), .clk_a(wbm_clk),
|
|
.q_b(tag), .adr_b(wbs_adr_slot), .clk_b(wbs_clk));
|
|
assign hit = wbs_adr_tag == tag;
|
|
vl_dpram_1r2w
|
|
# ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
|
|
dirty_mem (
|
|
.d_a(1'b1), .q_a(dirty), .adr_a(wbs_adr_slot), .we_a(wbs_cyc_i & wbs_we_i & wbs_ack_o), .clk_a(wbs_clk),
|
|
.d_b(1'b0), .adr_b(wbs_adr_slot), .we_b(mem_done), .clk_b(wbm_clk));
|
|
vl_wb_adr_inc # ( .adr_width(aw_s), .max_burst_width(wbs_max_burst_width)) adr_inc0 (
|
|
.cyc_i(wbs_cyc_i & (state==rdwr) & hit & valid),
|
|
.stb_i(wbs_stb_i & (state==rdwr) & hit & valid), // throttle depending on valid
|
.cti_i(wbs_cti_i),
|
.cti_i(wbs_cti_i),
|
.bte_i(wbs_bte_i),
|
.bte_i(wbs_bte_i),
|
.adr_i(wbs_adr_i),
|
.adr_i(wbs_adr_i),
|
.we_i (wbs_we_i),
|
.we_i (wbs_we_i),
|
.ack_o(wbs_ack_o),
|
.ack_o(wbs_ack_o),
|
.adr_o(wbs_adr),
|
.adr_o(wbs_adr),
|
.clk(wbsa_clk),
|
.clk(wbs_clk),
|
.rst(wbsa_rst));
|
.rst(wbs_rst));
|
vl_dpram_be_2r2w
|
vl_dpram_be_2r2w
|
# ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m) )
|
# ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m), .debug(debug))
|
cache_mem ( .d_a(wbs_dat_i), .adr_a(wbs_adr[aw_slot+aw_offset-1:0]), .be_a(wbs_sel_i), .we_a(wbs_cyc_i & wbs_we_i & wbs_ack_o), .q_a(wbs_dat_o), .clk_a(wbs_clk),
|
cache_mem ( .d_a(wbs_dat_i), .adr_a(wbs_adr[aw_slot+aw_offset-1:0]), .be_a(wbs_sel_i), .we_a(wbs_cyc_i & wbs_we_i & wbs_ack_o), .q_a(wbs_dat_o), .clk_a(wbs_clk),
|
.d_b(wbm_dat_i), .adr_b(wbm_adr), .be_b(wbm_sel_o), .we_b(wbm_cyc_o & !wbm_we_o & wbs_ack_i), .q_b(wbm_dat_o), .clk_b(wbm_clk));
|
.d_b(wbm_dat_i), .adr_b(wbm_adr_o[aw_slot+aw_offset-1:0]), .be_b(wbm_sel_o), .we_b(wbm_cyc_o & !wbm_we_o & wbs_ack_i), .q_b(wbm_dat_o), .clk_b(wbm_clk));
|
|
// .d_b(wbm_dat_i), .adr_b(wbm_adr), .be_b(wbm_sel_o), .we_b(wbm_cyc_o & !wbm_we_o & wbs_ack_i), .q_b(wbm_dat_o), .clk_b(wbm_clk));
|
always @ (posedge wbs_clk or posedge wbs_rst)
|
always @ (posedge wbs_clk or posedge wbs_rst)
|
if (wbs_rst)
|
if (wbs_rst)
|
state <= idle;
|
state <= idle;
|
else
|
else
|
case (state)
|
case (state)
|
idle:
|
idle:
|
if (wbs_cyc_i)
|
if (wbs_cyc_i)
|
state <= rdwr;
|
state <= rdwr;
|
rdwr:
|
rdwr:
|
if (wbs_we_i & valid & eoc)
|
casex ({valid, hit, dirty, eoc})
|
state <= idle;
|
4'b0xxx: state <= pull;
|
else if (wbs_we_i & !valid)
|
4'b11x1: state <= idle;
|
state <= pull;
|
4'b101x: state <= push;
|
else if (!wbs_we_i & valid & eoc)
|
4'b100x: state <= pull;
|
state <= idle;
|
endcase
|
else if (!wbs_we_i & !valid & !dirty)
|
|
state <= pull;
|
|
else if (!wbs_we_i & !valid & dirty)
|
|
state <= push;
|
|
push:
|
push:
|
if (done)
|
if (done)
|
state <= rdwr;
|
state <= rdwr;
|
pull:
|
pull:
|
if (done)
|
if (done)
|
Line 3009... |
Line 3148... |
default: state <= idle;
|
default: state <= idle;
|
endcase
|
endcase
|
// cdc
|
// cdc
|
generate
|
generate
|
if (async==1) begin : cdc0
|
if (async==1) begin : cdc0
|
vl_cdc cdc0 ( .start_pl(state==rdwr & !valid), .take_it_pl(mem_alert), .take_it_grant_pl(mem_done), .got_it_pl(done), .clk_src(wbs_clk), .rst_src(wbs_rst), .clk_dst(wbm_clk), .rst_dst(wbm_rst));
|
vl_cdc cdc0 ( .start_pl(state==rdwr & (!valid | !hit)), .take_it_pl(mem_alert), .take_it_grant_pl(mem_done), .got_it_pl(done), .clk_src(wbs_clk), .rst_src(wbs_rst), .clk_dst(wbm_clk), .rst_dst(wbm_rst));
|
end
|
end
|
else begin : nocdc
|
else begin : nocdc
|
assign mem_alert = state==rdwr & !valid;
|
assign mem_alert = state==rdwr & (!valid | !hit);
|
assign done = mem_done;
|
assign done = mem_done;
|
end
|
end
|
endgenerate
|
endgenerate
|
// FSM generating a number of burts 4 cycles
|
// FSM generating a number of burts 4 cycles
|
// actual number depends on data width ratio
|
// actual number depends on data width ratio
|
// nr_of_wbm_burst
|
// nr_of_wbm_burst
|
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt0;
|
reg [wbm_burst_width-1:0] cnt_rw, cnt_ack;
|
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt1;
|
|
always @ (posedge wbm_clk or posedge wbm_rst)
|
always @ (posedge wbm_clk or posedge wbm_rst)
|
if (wbm_rst)
|
if (wbm_rst)
|
cnt0 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
|
cnt_rw <= {wbm_burst_width{1'b0}};
|
else
|
else
|
if (wbm_radr_cke)
|
if (wbm_cyc_o & wbm_stb_o & !wbm_stall_i)
|
cnt0 <= cnt0 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
|
cnt_rw <= cnt_rw + 1;
|
assign wbm_radr_cke = wbm_cyc_o & wbm_stb_o & !wbm_stall_i;
|
|
assign wbm_radr = {wbs_adr_tag, tag, cnt0};
|
|
always @ (posedge wbm_clk or posedge wbm_rst)
|
always @ (posedge wbm_clk or posedge wbm_rst)
|
if (wbm_rst)
|
if (wbm_rst)
|
cnt1 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
|
cnt_ack <= {wbm_burst_width{1'b0}};
|
else
|
else
|
if (wbm_wadr_cke)
|
if (wbm_ack_i)
|
cnt1 <= cnt1 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
|
cnt_ack <= cnt_ack + 1;
|
assign wbm_wadr_cke = wbm_ack_i;
|
generate
|
assign wbm_wadr = {wbs_adr_tag, wbs_adr_slot, cnt1};
|
if (nr_of_wbm_burst_width==0) begin : one_burst
|
always @ (posedge wbm_clk or posedge wbm_rst)
|
always @ (posedge wbm_clk or posedge wbm_rst)
|
if (wbm_rst)
|
if (wbm_rst)
|
phase <= wbm_wait;
|
phase <= wbm_wait;
|
else
|
else
|
case (phase)
|
case (phase)
|
wbm_wait:
|
wbm_wait:
|
if (mem_alert)
|
if (mem_alert)
|
phase <= state;
|
if (state==push)
|
|
phase <= wbm_wr;
|
|
else
|
|
phase <= wbm_rd;
|
wbm_wr:
|
wbm_wr:
|
if (&cnt1 & wbm_ack_i)
|
if (&cnt_rw)
|
|
phase <= wbm_wr_drain;
|
|
wbm_wr_drain:
|
|
if (&cnt_ack)
|
phase <= wbm_rd;
|
phase <= wbm_rd;
|
wbm_rd:
|
wbm_rd:
|
if (&cnt0 & wbm_ack_i)
|
if (&cnt_rw)
|
phase <= idle;
|
phase <= wbm_rd_drain;
|
|
wbm_rd_drain:
|
|
if (&cnt_ack)
|
|
phase <= wbm_wait;
|
default: phase <= wbm_wait;
|
default: phase <= wbm_wait;
|
endcase
|
endcase
|
assign wbm_adr_o = (phase==wbm_wr) ? {tag, wbs_adr_slot, cnt1} : {wbs_adr_tag, wbs_adr_slot, cnt1};
|
assign mem_done = phase==wbm_rd_drain & (&cnt_ack) & wbm_ack_i;
|
assign wbm_adr = (phase==wbm_wr) ? {wbs_adr_slot, cnt1} : {wbs_adr_slot, cnt1};
|
end else begin : multiple_burst
|
assign wbm_cti_o = (&cnt0 | &cnt1) ? 3'b111 : 3'b010;
|
reg [nr_of_wbm_burst_width-1:0] cnt_burst;
|
|
end
|
|
endgenerate
|
|
assign wbm_adr_o = (phase[2]) ? {tag, wbs_adr_slot, cnt_rw} : {wbs_adr_tag, wbs_adr_slot, cnt_rw};
|
|
assign wbm_adr = (phase[2]) ? {wbs_adr_slot, cnt_rw} : {wbs_adr_slot, cnt_rw};
|
|
assign wbm_sel_o = {dw_m/8{1'b1}};
|
|
assign wbm_cti_o = (&cnt_rw | !wbm_stb_o) ? 3'b111 : 3'b010;
|
assign wbm_bte_o = bte;
|
assign wbm_bte_o = bte;
|
assign wbm_we_o = phase==wbm_wr;
|
assign {wbm_we_o, wbm_stb_o, wbm_cyc_o} = phase;
|
endmodule
|
endmodule
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Arithmetic functions ////
|
//// Arithmetic functions ////
|
//// ////
|
//// ////
|