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

Subversion Repositories versatile_library

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /versatile_library/trunk
    from Rev 99 to Rev 100
    Reverse comparison

Rev 99 → Rev 100

/rtl/verilog/versatile_library.v
47,6 → 47,7
`define RAM_BE
`define DPRAM_1R1W
`define DPRAM_2R1W
`define DPRAM_1R2W
`define DPRAM_2R2W
`define DPRAM_BE_2R2W
`define FIFO_1R1W_FILL_LEVEL_SYNC
154,20 → 155,26
`endif
`endif
 
`ifdef WBB3_WBB4_CACHE
`ifndef RAM
`define RAM
`endif
`ifndef WB_ADR_INC
`define WB_ADR_INC
`endif
`ifndef dpram_be_2r2w
`define DPRAM_BE_2R2W
`endif
`ifndef CDC
`define CDC
`endif
`endif
`ifdef WBB3_WBB4_CACHE
`ifndef RAM
`define RAM
`endif
`ifndef WB_ADR_INC
`define WB_ADR_INC
`endif
`ifndef DPRAM_1R1W
`define DPRAM_1R1W
`endif
`ifndef DPRAM_1R2W
`define DPRAM_1R2W
`endif
`ifndef DPRAM_BE_2R2W
`define DPRAM_BE_2R2W
`endif
`ifndef CDC
`define CDC
`endif
`endif
`ifdef MULTS18X18
`ifndef MULTS
293,7 → 300,7
`endif
 
// size to width
`define SIZE2WIDTH_EXPR = (`SIZE2WIDTH==4) ? 2 : (`SIZE2WIDTH==8) ? 3 : (`SIZE2WIDTH==16) ? 4 : (`SIZE2WIDTH==32) ? 5 : (`SIZE2WIDTH==64) ? 6 : (`SIZE2WIDTH==128) ? 7 : 8;
`define SIZE2WIDTH_EXPR = (`SIZE2WIDTH==1) ? 0 : (`SIZE2WIDTH==2) ? 1 : (`SIZE2WIDTH==4) ? 2 : (`SIZE2WIDTH==8) ? 3 : (`SIZE2WIDTH==16) ? 4 : (`SIZE2WIDTH==32) ? 5 : (`SIZE2WIDTH==64) ? 6 : (`SIZE2WIDTH==128) ? 7 : 8;
//////////////////////////////////////////////////////////////////////
//// ////
//// Versatile library, clock and reset ////
1232,9 → 1239,9
reg dff;
always @ (posedge clk or posedge rst)
if (rst)
{dff,q} <= 2'b00;
{q,dff} <= 2'b00;
else
{dff,q} <= {d,dff};
{q,dff} <= {dff,d};
endmodule
`endif
 
1270,7 → 1277,7
`define MODULE toggle2pulse
`BASE`MODULE t2p0 (
`undef MODULE
.d(take_it_sync),
.d(take_it_tg_sync),
.pl(take_it_pl),
.clk(clk_dst),
.rst(rst_dst));
1295,7 → 1302,7
`define MODULE toggle2pulse
`BASE`MODULE t2p1 (
`undef MODULE
.d(take_it_grant_tg_sync),
.d(got_it_tg_sync),
.pl(got_it_pl),
.clk(clk_src),
.rst(rst_src));
3785,6 → 3792,7
parameter data_width = 32;
parameter addr_width = 8;
parameter mem_size = 1<<addr_width;
parameter debug = 0;
input [(data_width-1):0] d;
input [(addr_width-1):0] adr;
input we;
3791,16 → 3799,30
output reg [(data_width-1):0] q;
input clk;
reg [data_width-1:0] ram [mem_size-1:0];
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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)
if (we)
$display ("Value %h written at address %h : time %t", d, adr, $time);
end
endgenerate
always @ (posedge clk)
begin
if (we)
3836,14 → 3858,18
wire [data_width/8-1:0] cke;
`endif
 
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (memory_init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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
 
`ifdef SYSTEMVERILOG
3909,18 → 3935,33
output [(data_width-1):0] q_b;
input clk_a, clk_b;
reg [(addr_width-1):0] adr_b_reg;
reg [data_width-1:0] ram [mem_szie-1:0] `SYN_NO_RW_CHECK;
reg [data_width-1:0] ram [mem_size-1:0] `SYN_NO_RW_CHECK;
 
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
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);
end
endgenerate
 
always @ (posedge clk_a)
if (we_a)
ram[adr_a] <= d_a;
3949,16 → 3990,31
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_szie-1:0] `SYN_NO_RW_CHECK;
 
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
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);
end
endgenerate
 
always @ (posedge clk_a)
begin
q_a <= ram[adr_a];
3970,6 → 4026,66
endmodule
`endif
 
`ifdef DPRAM_1R2W
`define MODULE dpram_1r2w
module `BASE`MODULE ( d_a, q_a, adr_a, we_a, clk_a, d_b, adr_b, we_b, clk_b );
`undef MODULE
 
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] `SYN_NO_RW_CHECK;
 
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
`endif
 
`ifdef DPRAM_2R2W
`define MODULE dpram_2r2w
module `BASE`MODULE ( d_a, q_a, adr_a, we_a, clk_a, d_b, q_b, adr_b, we_b, clk_b );
3990,16 → 4106,33
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_size-1:0] `SYN_NO_RW_CHECK;
 
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
parameter debug = 0;
generate
if (memory_init) 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];
4028,8 → 4161,9
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 init = 0;
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
parameter debug = 0;
input [(a_data_width-1):0] d_a;
input [(a_addr_width-1):0] adr_a;
4043,6 → 4177,18
output reg [(b_data_width-1):0] q_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
// use a multi-dimensional packed array
//to model individual bytes within the word
4053,16 → 4199,22
logic [0:3][7:0] ram [0:mem_size-1] `SYN_NO_RW_CHECK;
initial
if (init)
if (memory_init==1)
$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)
begin
if(we_a) begin
if(be_a[3]) ram[adr_a][3] <= d_a[31:24];
if(be_a[2]) ram[adr_a][2] <= d_a[23:16];
if(be_a[1]) ram[adr_a][1] <= d_a[15:8];
if(be_a[0]) ram[adr_a][0] <= d_a[7:0];
if(be_a[3]) ram[adr_a][0] <= d_a[31:24];
if(be_a[2]) ram[adr_a][1] <= d_a[23:16];
if(be_a[1]) ram[adr_a][2] <= d_a[15:8];
if(be_a[0]) ram[adr_a][3] <= d_a[7:0];
end
end
4072,10 → 4224,10
always_ff@(posedge clk_b)
begin
if(we_b) begin
if(be_b[3]) ram[adr_b][3] <= d_b[31:24];
if(be_b[2]) ram[adr_b][2] <= d_b[23:16];
if(be_b[1]) ram[adr_b][1] <= d_b[15:8];
if(be_b[0]) ram[adr_b][0] <= d_b[7:0];
if(be_b[3]) ram[adr_b][0] <= d_b[31:24];
if(be_b[2]) ram[adr_b][1] <= d_b[23:16];
if(be_b[1]) ram[adr_b][2] <= d_b[15:8];
if(be_b[0]) ram[adr_b][3] <= d_b[7:0];
end
end
4091,8 → 4243,14
logic [0:7][7:0] ram [0:mem_size-1] `SYN_NO_RW_CHECK;
initial
if (init)
if (memory_init==1)
$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)
begin
4135,7 → 4293,7
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
logic [31:0] temp;
`define MODULE dpram_be_2r2w
`BASE`MODULE # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(init), .memory_file(memory_file))
`BASE`MODULE # (.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))
`undef MODULE
dpram6464 (
.d_a(d_a),
4152,7 → 4310,7
.clk_b(clk_b)
);
 
always_comb
always @ (adr_b[0] or temp)
if (adr_b[0])
q_b = temp[31:16];
else
4165,7 → 4323,7
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
logic [63:0] temp;
`define MODULE dpram_be_2r2w
`BASE`MODULE # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(init), .memory_file(memory_file))
`BASE`MODULE # (.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))
`undef MODULE
dpram6464 (
.d_a({d_a,d_a}),
4182,7 → 4340,7
.clk_b(clk_b)
);
 
always_comb
always @ (adr_a[0] or temp)
if (adr_a[0])
q_a = temp[63:32];
else
5582,8 → 5740,12
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);
 
parameter dat_width = 32;
parameter adr_width = 8;
parameter dat_width = 32;
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 [adr_width-1:0] wb_adr_i;
5590,7 → 5752,6
input [dat_width/8-1:0] wb_sel_i;
input wb_we_i, wb_stb_i, wb_cyc_i;
output [dat_width-1:0] wb_dat_o;
reg [dat_width-1:0] wb_dat_o;
output wb_stall_o;
output wb_ack_o;
reg wb_ack_o;
5598,29 → 5759,22
 
wire [dat_width/8-1:0] cke;
 
generate
if (dat_width==32) begin
reg [7:0] ram3 [1<<(adr_width-2)-1:0];
reg [7:0] ram2 [1<<(adr_width-2)-1:0];
reg [7:0] ram1 [1<<(adr_width-2)-1:0];
reg [7:0] ram0 [1<<(adr_width-2)-1:0];
assign cke = wb_sel_i & {(dat_width/8){wb_we_i}};
always @ (posedge wb_clk)
begin
if (cke[3]) ram3[wb_adr_i[adr_width-1:2]] <= wb_dat_i[31:24];
if (cke[2]) ram2[wb_adr_i[adr_width-1:2]] <= wb_dat_i[23:16];
if (cke[1]) ram1[wb_adr_i[adr_width-1:2]] <= wb_dat_i[15:8];
if (cke[0]) ram0[wb_adr_i[adr_width-1:2]] <= wb_dat_i[7:0];
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
`define MODULE ram_be
`BASE`MODULE # (
.data_width(dat_width),
.addr_width(adr_width),
.mem_size(mem_size),
.memory_init(memory_init),
.memory_file(memory_file))
ram0(
`undef MODULE
.d(wb_dat_i),
.adr(wb_adr_i),
.be(wb_sel_i),
.we(wb_we_i & wb_stb_i & wb_cyc_i),
.q(wb_dat_o),
.clk(wb_clk)
);
 
always @ (posedge wb_clk or posedge wb_rst)
if (wb_rst)
5853,8 → 6007,8
parameter dw_s = 32;
parameter aw_s = 24;
parameter dw_m = dw_s;
parameter aw_m = dw_s * aw_s / dw_m;
parameter max_burst_width = 4;
localparam aw_m = dw_s * aw_s / dw_m;
parameter wbs_max_burst_width = 4;
 
parameter async = 1; // wbs_clk != wbm_clk
 
5861,6 → 6015,11
parameter nr_of_ways = 1;
parameter aw_offset = 4; // 4 => 16 words per cache line
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;
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;
5871,6 → 6030,7
`define SIZE2WIDTH nr_of_wbm_burst
localparam nr_of_wbm_burst_width `SIZE2WIDTH_EXPR
`undef SIZE2WIDTH
 
input [dw_s-1:0] wbs_dat_i;
input [aw_s-1:0] wbs_adr_i; // dont include a1,a0
input [dw_s/8-1:0] wbs_sel_i;
5892,7 → 6052,7
input wbm_stall_i;
input wbm_clk, wbm_rst;
 
wire dirty, valid;
wire valid, dirty, hit;
wire [aw_tag-1:0] tag;
wire tag_mem_we;
wire [aw_tag-1:0] wbs_adr_tag;
5913,28 → 6073,53
// wbm side
reg [aw_m-1:0] wbm_radr;
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;
 
reg [1:0] phase;
localparam wbm_wait = 2'b00;
localparam wbm_rd = 2'b10;
localparam wbm_wr = 2'b11;
reg [2:0] phase;
// phase = {we,stb,cyc}
localparam wbm_wait = 3'b000;
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 eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
 
`define MODULE ram
generate
if (valid_mem==0) begin : no_valid_mem
assign valid = 1'b1;
end else begin : valid_mem_inst
`define MODULE dpram_1r1w
`BASE`MODULE
# ( .data_width(aw_tag), .addr_width(aw_slot))
tag_mem ( .d(wbs_adr_slot), .adr(wbs_adr_tag), .we(done), .q(tag), .clk(wbs_clk));
# ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
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));
`undef MODULE
assign valid = wbs_adr_tag == tag;
end
endgenerate
 
`define MODULE dpram_1r1w
`BASE`MODULE
# ( .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;
`undef MODULE
 
`define MODULE dpram_1r2w
`BASE`MODULE
# ( .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));
`undef MODULE
 
`define MODULE wb_adr_inc
`BASE`MODULE # ( .adr_width(aw_s), .max_burst_width(max_burst_width)) adr_inc0 (
.cyc_i(wbs_cyc_i),
.stb_i(wbs_stb_i & (state==idle | (state==rw & valid))), // throttle depending on valid
`BASE`MODULE # ( .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),
.bte_i(wbs_bte_i),
.adr_i(wbs_adr_i),
5941,15 → 6126,16
.we_i (wbs_we_i),
.ack_o(wbs_ack_o),
.adr_o(wbs_adr),
.clk(wbsa_clk),
.rst(wbsa_rst));
.clk(wbs_clk),
.rst(wbs_rst));
`undef MODULE
 
`define MODULE dpram_be_2r2w
`BASE`MODULE
# ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m) )
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));
# ( .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),
.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));
`undef MODULE
 
always @ (posedge wbs_clk or posedge wbs_rst)
5961,16 → 6147,12
if (wbs_cyc_i)
state <= rdwr;
rdwr:
if (wbs_we_i & valid & eoc)
state <= idle;
else if (wbs_we_i & !valid)
state <= pull;
else if (!wbs_we_i & valid & eoc)
state <= idle;
else if (!wbs_we_i & !valid & !dirty)
state <= pull;
else if (!wbs_we_i & !valid & dirty)
state <= push;
casex ({valid, hit, dirty, eoc})
4'b0xxx: state <= pull;
4'b11x1: state <= idle;
4'b101x: state <= push;
4'b100x: state <= pull;
endcase
push:
if (done)
state <= rdwr;
5980,16 → 6162,15
default: state <= idle;
endcase
 
 
// cdc
generate
if (async==1) begin : cdc0
`define MODULE cdc
`BASE`MODULE 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));
`BASE`MODULE 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));
`undef MODULE
end
else begin : nocdc
assign mem_alert = state==rdwr & !valid;
assign mem_alert = state==rdwr & (!valid | !hit);
assign done = mem_done;
end
endgenerate
5997,27 → 6178,25
// FSM generating a number of burts 4 cycles
// actual number depends on data width ratio
// nr_of_wbm_burst
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt0;
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt1;
reg [wbm_burst_width-1:0] cnt_rw, cnt_ack;
 
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt0 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_rw <= {wbm_burst_width{1'b0}};
else
if (wbm_radr_cke)
cnt0 <= cnt0 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_radr_cke = wbm_cyc_o & wbm_stb_o & !wbm_stall_i;
assign wbm_radr = {wbs_adr_tag, tag, cnt0};
if (wbm_cyc_o & wbm_stb_o & !wbm_stall_i)
cnt_rw <= cnt_rw + 1;
 
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt1 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_ack <= {wbm_burst_width{1'b0}};
else
if (wbm_wadr_cke)
cnt1 <= cnt1 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_wadr_cke = wbm_ack_i;
assign wbm_wadr = {wbs_adr_tag, wbs_adr_slot, cnt1};
if (wbm_ack_i)
cnt_ack <= cnt_ack + 1;
 
generate
if (nr_of_wbm_burst_width==0) begin : one_burst
 
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
phase <= wbm_wait;
6025,21 → 6204,41
case (phase)
wbm_wait:
if (mem_alert)
phase <= state;
if (state==push)
phase <= wbm_wr;
else
phase <= wbm_rd;
wbm_wr:
if (&cnt1 & wbm_ack_i)
if (&cnt_rw)
phase <= wbm_wr_drain;
wbm_wr_drain:
if (&cnt_ack)
phase <= wbm_rd;
wbm_rd:
if (&cnt0 & wbm_ack_i)
phase <= idle;
if (&cnt_rw)
phase <= wbm_rd_drain;
wbm_rd_drain:
if (&cnt_ack)
phase <= wbm_wait;
default: phase <= wbm_wait;
endcase
 
assign wbm_adr_o = (phase==wbm_wr) ? {tag, wbs_adr_slot, cnt1} : {wbs_adr_tag, wbs_adr_slot, cnt1};
assign wbm_adr = (phase==wbm_wr) ? {wbs_adr_slot, cnt1} : {wbs_adr_slot, cnt1};
assign wbm_cti_o = (&cnt0 | &cnt1) ? 3'b111 : 3'b010;
assign mem_done = phase==wbm_rd_drain & (&cnt_ack) & wbm_ack_i;
end else begin : multiple_burst
 
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_we_o = phase==wbm_wr;
assign {wbm_we_o, wbm_stb_o, wbm_cyc_o} = phase;
 
endmodule
`endif
/rtl/verilog/versatile_library_actel.v
425,9 → 425,9
reg dff;
always @ (posedge clk or posedge rst)
if (rst)
{dff,q} <= 2'b00;
{q,dff} <= 2'b00;
else
{dff,q} <= {d,dff};
{q,dff} <= {dff,d};
endmodule
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;
450,7 → 450,7
.clk(clk_dst),
.rst(rst_dst));
vl_toggle2pulse t2p0 (
.d(take_it_sync),
.d(take_it_tg_sync),
.pl(take_it_pl),
.clk(clk_dst),
.rst(rst_dst));
466,7 → 466,7
.clk(clk_src),
.rst(rst_src));
vl_toggle2pulse t2p1 (
.d(take_it_grant_tg_sync),
.d(got_it_tg_sync),
.pl(got_it_pl),
.clk(clk_src),
.rst(rst_src));
1290,6 → 1290,7
parameter data_width = 32;
parameter addr_width = 8;
parameter mem_size = 1<<addr_width;
parameter debug = 0;
input [(data_width-1):0] d;
input [(addr_width-1):0] adr;
input we;
1296,15 → 1297,26
output reg [(data_width-1):0] q;
input clk;
reg [data_width-1:0] ram [mem_size-1:0];
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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)
if (we)
$display ("Value %h written at address %h : time %t", d, adr, $time);
end
endgenerate
always @ (posedge clk)
begin
if (we)
1330,14 → 1342,18
reg [data_width-1:0] ram [mem_size-1:0];
wire [data_width/8-1:0] cke;
`endif
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (memory_init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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
`ifdef SYSTEMVERILOG
always_ff@(posedge clk)
1389,16 → 1405,28
output [(data_width-1):0] q_b;
input clk_a, clk_b;
reg [(addr_width-1):0] adr_b_reg;
reg [data_width-1:0] ram [mem_szie-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
reg [data_width-1:0] ram [mem_size-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
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);
end
endgenerate
always @ (posedge clk_a)
if (we_a)
ram[adr_a] <= d_a;
1419,15 → 1447,27
input clk_a, clk_b;
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_szie-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
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);
end
endgenerate
always @ (posedge clk_a)
begin
q_a <= ram[adr_a];
1437,6 → 1477,56
always @ (posedge clk_b)
q_b <= ram[adr_b];
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] /*synthesis syn_ramstyle = "no_rw_check"*/;
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 );
parameter data_width = 32;
parameter addr_width = 8;
1452,15 → 1542,30
input clk_a, clk_b;
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_size-1:0] /*synthesis syn_ramstyle = "no_rw_check"*/;
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
parameter debug = 0;
generate
if (memory_init) 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];
1481,8 → 1586,9
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);
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 debug = 0;
input [(a_data_width-1):0] d_a;
input [(a_addr_width-1):0] adr_a;
input [(a_data_width/8-1):0] be_a;
1494,6 → 1600,16
input we_b;
output reg [(b_data_width-1):0] q_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
// use a multi-dimensional packed array
//to model individual bytes within the word
1501,15 → 1617,20
if (a_data_width==32 & b_data_width==32) begin : dpram_3232
logic [0:3][7:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
initial
if (init)
if (memory_init==1)
$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)
begin
if(we_a) begin
if(be_a[3]) ram[adr_a][3] <= d_a[31:24];
if(be_a[2]) ram[adr_a][2] <= d_a[23:16];
if(be_a[1]) ram[adr_a][1] <= d_a[15:8];
if(be_a[0]) ram[adr_a][0] <= d_a[7:0];
if(be_a[3]) ram[adr_a][0] <= d_a[31:24];
if(be_a[2]) ram[adr_a][1] <= d_a[23:16];
if(be_a[1]) ram[adr_a][2] <= d_a[15:8];
if(be_a[0]) ram[adr_a][3] <= d_a[7:0];
end
end
always@(posedge clk_a)
1517,10 → 1638,10
always_ff@(posedge clk_b)
begin
if(we_b) begin
if(be_b[3]) ram[adr_b][3] <= d_b[31:24];
if(be_b[2]) ram[adr_b][2] <= d_b[23:16];
if(be_b[1]) ram[adr_b][1] <= d_b[15:8];
if(be_b[0]) ram[adr_b][0] <= d_b[7:0];
if(be_b[3]) ram[adr_b][0] <= d_b[31:24];
if(be_b[2]) ram[adr_b][1] <= d_b[23:16];
if(be_b[1]) ram[adr_b][2] <= d_b[15:8];
if(be_b[0]) ram[adr_b][3] <= d_b[7:0];
end
end
always@(posedge clk_b)
1531,8 → 1652,13
if (a_data_width==64 & b_data_width==64) begin : dpram_6464
logic [0:7][7:0] ram [0:mem_size-1] /*synthesis syn_ramstyle = "no_rw_check"*/;
initial
if (init)
if (memory_init==1)
$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)
begin
if(we_a) begin
1568,7 → 1694,7
generate
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
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 (
.d_a(d_a),
.q_a(q_a),
1583,7 → 1709,7
.we_b(we_b),
.clk_b(clk_b)
);
always_comb
always @ (adr_b[0] or temp)
if (adr_b[0])
q_b = temp[31:16];
else
1593,7 → 1719,7
generate
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
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 (
.d_a({d_a,d_a}),
.q_a(temp),
1608,7 → 1734,7
.we_b(we_b),
.clk_b(clk_b)
);
always_comb
always @ (adr_a[0] or temp)
if (adr_a[0])
q_a = temp[63:32];
else
2657,42 → 2783,36
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_o, wb_stall_o, wb_ack_o, wb_clk, wb_rst);
parameter dat_width = 32;
parameter adr_width = 8;
parameter dat_width = 32;
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 [adr_width-1:0] wb_adr_i;
input [dat_width/8-1:0] wb_sel_i;
input wb_we_i, wb_stb_i, wb_cyc_i;
output [dat_width-1:0] wb_dat_o;
reg [dat_width-1:0] wb_dat_o;
output wb_stall_o;
output wb_ack_o;
reg wb_ack_o;
input wb_clk, wb_rst;
wire [dat_width/8-1:0] cke;
generate
if (dat_width==32) begin
reg [7:0] ram3 [1<<(adr_width-2)-1:0];
reg [7:0] ram2 [1<<(adr_width-2)-1:0];
reg [7:0] ram1 [1<<(adr_width-2)-1:0];
reg [7:0] ram0 [1<<(adr_width-2)-1:0];
assign cke = wb_sel_i & {(dat_width/8){wb_we_i}};
always @ (posedge wb_clk)
begin
if (cke[3]) ram3[wb_adr_i[adr_width-1:2]] <= wb_dat_i[31:24];
if (cke[2]) ram2[wb_adr_i[adr_width-1:2]] <= wb_dat_i[23:16];
if (cke[1]) ram1[wb_adr_i[adr_width-1:2]] <= wb_dat_i[15:8];
if (cke[0]) ram0[wb_adr_i[adr_width-1:2]] <= wb_dat_i[7:0];
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
vl_ram_be # (
.data_width(dat_width),
.addr_width(adr_width),
.mem_size(mem_size),
.memory_init(memory_init),
.memory_file(memory_file))
ram0(
.d(wb_dat_i),
.adr(wb_adr_i),
.be(wb_sel_i),
.we(wb_we_i & wb_stb_i & wb_cyc_i),
.q(wb_dat_o),
.clk(wb_clk)
);
always @ (posedge wb_clk or posedge wb_rst)
if (wb_rst)
wb_ack_o <= 1'b0;
2800,18 → 2920,21
parameter dw_s = 32;
parameter aw_s = 24;
parameter dw_m = dw_s;
parameter aw_m = dw_s * aw_s / dw_m;
parameter max_burst_width = 4;
localparam aw_m = dw_s * aw_s / dw_m;
parameter wbs_max_burst_width = 4;
parameter async = 1; // wbs_clk != wbm_clk
parameter nr_of_ways = 1;
parameter aw_offset = 4; // 4 => 16 words per cache line
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;
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 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_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 [aw_s-1:0] wbs_adr_i; // dont include a1,a0
input [dw_s/8-1:0] wbs_sel_i;
2831,7 → 2954,7
input wbm_ack_i;
input wbm_stall_i;
input wbm_clk, wbm_rst;
wire dirty, valid;
wire valid, dirty, hit;
wire [aw_tag-1:0] tag;
wire tag_mem_we;
wire [aw_tag-1:0] wbs_adr_tag;
2849,21 → 2972,40
// wbm side
reg [aw_m-1:0] wbm_radr;
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;
reg [1:0] phase;
localparam wbm_wait = 2'b00;
localparam wbm_rd = 2'b10;
localparam wbm_wr = 2'b11;
reg [2:0] phase;
// phase = {we,stb,cyc}
localparam wbm_wait = 3'b000;
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 eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
vl_ram
# ( .data_width(aw_tag), .addr_width(aw_slot))
tag_mem ( .d(wbs_adr_slot), .adr(wbs_adr_tag), .we(done), .q(tag), .clk(wbs_clk));
assign valid = wbs_adr_tag == tag;
vl_wb_adr_inc # ( .adr_width(aw_s), .max_burst_width(max_burst_width)) adr_inc0 (
.cyc_i(wbs_cyc_i),
.stb_i(wbs_stb_i & (state==idle | (state==rw & valid))), // throttle depending on valid
generate
if (valid_mem==0) begin : no_valid_mem
assign valid = 1'b1;
end else begin : valid_mem_inst
vl_dpram_1r1w
# ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
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),
.bte_i(wbs_bte_i),
.adr_i(wbs_adr_i),
2870,12 → 3012,13
.we_i (wbs_we_i),
.ack_o(wbs_ack_o),
.adr_o(wbs_adr),
.clk(wbsa_clk),
.rst(wbsa_rst));
.clk(wbs_clk),
.rst(wbs_rst));
vl_dpram_be_2r2w
# ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m) )
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));
# ( .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),
.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)
if (wbs_rst)
state <= idle;
2885,16 → 3028,12
if (wbs_cyc_i)
state <= rdwr;
rdwr:
if (wbs_we_i & valid & eoc)
state <= idle;
else if (wbs_we_i & !valid)
state <= pull;
else if (!wbs_we_i & valid & eoc)
state <= idle;
else if (!wbs_we_i & !valid & !dirty)
state <= pull;
else if (!wbs_we_i & !valid & dirty)
state <= push;
casex ({valid, hit, dirty, eoc})
4'b0xxx: state <= pull;
4'b11x1: state <= idle;
4'b101x: state <= push;
4'b100x: state <= pull;
endcase
push:
if (done)
state <= rdwr;
2906,10 → 3045,10
// cdc
generate
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
else begin : nocdc
assign mem_alert = state==rdwr & !valid;
assign mem_alert = state==rdwr & (!valid | !hit);
assign done = mem_done;
end
endgenerate
2916,24 → 3055,21
// FSM generating a number of burts 4 cycles
// actual number depends on data width ratio
// nr_of_wbm_burst
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt0;
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt1;
reg [wbm_burst_width-1:0] cnt_rw, cnt_ack;
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt0 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_rw <= {wbm_burst_width{1'b0}};
else
if (wbm_radr_cke)
cnt0 <= cnt0 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_radr_cke = wbm_cyc_o & wbm_stb_o & !wbm_stall_i;
assign wbm_radr = {wbs_adr_tag, tag, cnt0};
if (wbm_cyc_o & wbm_stb_o & !wbm_stall_i)
cnt_rw <= cnt_rw + 1;
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt1 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_ack <= {wbm_burst_width{1'b0}};
else
if (wbm_wadr_cke)
cnt1 <= cnt1 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_wadr_cke = wbm_ack_i;
assign wbm_wadr = {wbs_adr_tag, wbs_adr_slot, cnt1};
if (wbm_ack_i)
cnt_ack <= cnt_ack + 1;
generate
if (nr_of_wbm_burst_width==0) begin : one_burst
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
phase <= wbm_wait;
2941,20 → 3077,35
case (phase)
wbm_wait:
if (mem_alert)
phase <= state;
if (state==push)
phase <= wbm_wr;
else
phase <= wbm_rd;
wbm_wr:
if (&cnt1 & wbm_ack_i)
if (&cnt_rw)
phase <= wbm_wr_drain;
wbm_wr_drain:
if (&cnt_ack)
phase <= wbm_rd;
wbm_rd:
if (&cnt0 & wbm_ack_i)
phase <= idle;
if (&cnt_rw)
phase <= wbm_rd_drain;
wbm_rd_drain:
if (&cnt_ack)
phase <= wbm_wait;
default: phase <= wbm_wait;
endcase
assign wbm_adr_o = (phase==wbm_wr) ? {tag, wbs_adr_slot, cnt1} : {wbs_adr_tag, wbs_adr_slot, cnt1};
assign wbm_adr = (phase==wbm_wr) ? {wbs_adr_slot, cnt1} : {wbs_adr_slot, cnt1};
assign wbm_cti_o = (&cnt0 | &cnt1) ? 3'b111 : 3'b010;
assign mem_done = phase==wbm_rd_drain & (&cnt_ack) & wbm_ack_i;
end else begin : multiple_burst
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_we_o = phase==wbm_wr;
assign {wbm_we_o, wbm_stb_o, wbm_cyc_o} = phase;
endmodule
//////////////////////////////////////////////////////////////////////
//// ////
/rtl/verilog/wb.v
41,7 → 41,6
//////////////////////////////////////////////////////////////////////
 
`ifdef WB_ADR_INC
// async wb3 - wb3 bridge
`timescale 1ns/1ns
`define MODULE wb_adr_inc
module `BASE`MODULE ( cyc_i, stb_i, cti_i, bte_i, adr_i, we_i, ack_o, adr_o, clk, rst);
879,8 → 878,12
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);
 
parameter dat_width = 32;
parameter adr_width = 8;
parameter dat_width = 32;
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 [adr_width-1:0] wb_adr_i;
887,7 → 890,6
input [dat_width/8-1:0] wb_sel_i;
input wb_we_i, wb_stb_i, wb_cyc_i;
output [dat_width-1:0] wb_dat_o;
reg [dat_width-1:0] wb_dat_o;
output wb_stall_o;
output wb_ack_o;
reg wb_ack_o;
895,29 → 897,22
 
wire [dat_width/8-1:0] cke;
 
generate
if (dat_width==32) begin
reg [7:0] ram3 [1<<(adr_width-2)-1:0];
reg [7:0] ram2 [1<<(adr_width-2)-1:0];
reg [7:0] ram1 [1<<(adr_width-2)-1:0];
reg [7:0] ram0 [1<<(adr_width-2)-1:0];
assign cke = wb_sel_i & {(dat_width/8){wb_we_i}};
always @ (posedge wb_clk)
begin
if (cke[3]) ram3[wb_adr_i[adr_width-1:2]] <= wb_dat_i[31:24];
if (cke[2]) ram2[wb_adr_i[adr_width-1:2]] <= wb_dat_i[23:16];
if (cke[1]) ram1[wb_adr_i[adr_width-1:2]] <= wb_dat_i[15:8];
if (cke[0]) ram0[wb_adr_i[adr_width-1:2]] <= wb_dat_i[7:0];
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
`define MODULE ram_be
`BASE`MODULE # (
.data_width(dat_width),
.addr_width(adr_width),
.mem_size(mem_size),
.memory_init(memory_init),
.memory_file(memory_file))
ram0(
`undef MODULE
.d(wb_dat_i),
.adr(wb_adr_i),
.be(wb_sel_i),
.we(wb_we_i & wb_stb_i & wb_cyc_i),
.q(wb_dat_o),
.clk(wb_clk)
);
 
always @ (posedge wb_clk or posedge wb_rst)
if (wb_rst)
1150,8 → 1145,8
parameter dw_s = 32;
parameter aw_s = 24;
parameter dw_m = dw_s;
parameter aw_m = dw_s * aw_s / dw_m;
parameter max_burst_width = 4;
localparam aw_m = dw_s * aw_s / dw_m;
parameter wbs_max_burst_width = 4;
 
parameter async = 1; // wbs_clk != wbm_clk
 
1158,6 → 1153,11
parameter nr_of_ways = 1;
parameter aw_offset = 4; // 4 => 16 words per cache line
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;
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;
1168,6 → 1168,7
`define SIZE2WIDTH nr_of_wbm_burst
localparam nr_of_wbm_burst_width `SIZE2WIDTH_EXPR
`undef SIZE2WIDTH
 
input [dw_s-1:0] wbs_dat_i;
input [aw_s-1:0] wbs_adr_i; // dont include a1,a0
input [dw_s/8-1:0] wbs_sel_i;
1189,7 → 1190,7
input wbm_stall_i;
input wbm_clk, wbm_rst;
 
wire dirty, valid;
wire valid, dirty, hit;
wire [aw_tag-1:0] tag;
wire tag_mem_we;
wire [aw_tag-1:0] wbs_adr_tag;
1210,28 → 1211,53
// wbm side
reg [aw_m-1:0] wbm_radr;
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;
 
reg [1:0] phase;
localparam wbm_wait = 2'b00;
localparam wbm_rd = 2'b10;
localparam wbm_wr = 2'b11;
reg [2:0] phase;
// phase = {we,stb,cyc}
localparam wbm_wait = 3'b000;
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 eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
 
`define MODULE ram
generate
if (valid_mem==0) begin : no_valid_mem
assign valid = 1'b1;
end else begin : valid_mem_inst
`define MODULE dpram_1r1w
`BASE`MODULE
# ( .data_width(aw_tag), .addr_width(aw_slot))
tag_mem ( .d(wbs_adr_slot), .adr(wbs_adr_tag), .we(done), .q(tag), .clk(wbs_clk));
# ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
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));
`undef MODULE
assign valid = wbs_adr_tag == tag;
end
endgenerate
 
`define MODULE dpram_1r1w
`BASE`MODULE
# ( .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;
`undef MODULE
 
`define MODULE dpram_1r2w
`BASE`MODULE
# ( .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));
`undef MODULE
 
`define MODULE wb_adr_inc
`BASE`MODULE # ( .adr_width(aw_s), .max_burst_width(max_burst_width)) adr_inc0 (
.cyc_i(wbs_cyc_i),
.stb_i(wbs_stb_i & (state==idle | (state==rw & valid))), // throttle depending on valid
`BASE`MODULE # ( .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),
.bte_i(wbs_bte_i),
.adr_i(wbs_adr_i),
1238,15 → 1264,16
.we_i (wbs_we_i),
.ack_o(wbs_ack_o),
.adr_o(wbs_adr),
.clk(wbsa_clk),
.rst(wbsa_rst));
.clk(wbs_clk),
.rst(wbs_rst));
`undef MODULE
 
`define MODULE dpram_be_2r2w
`BASE`MODULE
# ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m) )
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));
# ( .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),
.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));
`undef MODULE
 
always @ (posedge wbs_clk or posedge wbs_rst)
1258,16 → 1285,12
if (wbs_cyc_i)
state <= rdwr;
rdwr:
if (wbs_we_i & valid & eoc)
state <= idle;
else if (wbs_we_i & !valid)
state <= pull;
else if (!wbs_we_i & valid & eoc)
state <= idle;
else if (!wbs_we_i & !valid & !dirty)
state <= pull;
else if (!wbs_we_i & !valid & dirty)
state <= push;
casex ({valid, hit, dirty, eoc})
4'b0xxx: state <= pull;
4'b11x1: state <= idle;
4'b101x: state <= push;
4'b100x: state <= pull;
endcase
push:
if (done)
state <= rdwr;
1277,16 → 1300,15
default: state <= idle;
endcase
 
 
// cdc
generate
if (async==1) begin : cdc0
`define MODULE cdc
`BASE`MODULE 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));
`BASE`MODULE 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));
`undef MODULE
end
else begin : nocdc
assign mem_alert = state==rdwr & !valid;
assign mem_alert = state==rdwr & (!valid | !hit);
assign done = mem_done;
end
endgenerate
1294,27 → 1316,25
// FSM generating a number of burts 4 cycles
// actual number depends on data width ratio
// nr_of_wbm_burst
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt0;
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt1;
reg [wbm_burst_width-1:0] cnt_rw, cnt_ack;
 
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt0 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_rw <= {wbm_burst_width{1'b0}};
else
if (wbm_radr_cke)
cnt0 <= cnt0 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_radr_cke = wbm_cyc_o & wbm_stb_o & !wbm_stall_i;
assign wbm_radr = {wbs_adr_tag, tag, cnt0};
if (wbm_cyc_o & wbm_stb_o & !wbm_stall_i)
cnt_rw <= cnt_rw + 1;
 
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt1 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_ack <= {wbm_burst_width{1'b0}};
else
if (wbm_wadr_cke)
cnt1 <= cnt1 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_wadr_cke = wbm_ack_i;
assign wbm_wadr = {wbs_adr_tag, wbs_adr_slot, cnt1};
if (wbm_ack_i)
cnt_ack <= cnt_ack + 1;
 
generate
if (nr_of_wbm_burst_width==0) begin : one_burst
 
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
phase <= wbm_wait;
1322,21 → 1342,41
case (phase)
wbm_wait:
if (mem_alert)
phase <= state;
if (state==push)
phase <= wbm_wr;
else
phase <= wbm_rd;
wbm_wr:
if (&cnt1 & wbm_ack_i)
if (&cnt_rw)
phase <= wbm_wr_drain;
wbm_wr_drain:
if (&cnt_ack)
phase <= wbm_rd;
wbm_rd:
if (&cnt0 & wbm_ack_i)
phase <= idle;
if (&cnt_rw)
phase <= wbm_rd_drain;
wbm_rd_drain:
if (&cnt_ack)
phase <= wbm_wait;
default: phase <= wbm_wait;
endcase
 
assign wbm_adr_o = (phase==wbm_wr) ? {tag, wbs_adr_slot, cnt1} : {wbs_adr_tag, wbs_adr_slot, cnt1};
assign wbm_adr = (phase==wbm_wr) ? {wbs_adr_slot, cnt1} : {wbs_adr_slot, cnt1};
assign wbm_cti_o = (&cnt0 | &cnt1) ? 3'b111 : 3'b010;
assign mem_done = phase==wbm_rd_drain & (&cnt_ack) & wbm_ack_i;
end else begin : multiple_burst
 
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_we_o = phase==wbm_wr;
assign {wbm_we_o, wbm_stb_o, wbm_cyc_o} = phase;
 
endmodule
`endif
/rtl/verilog/versatile_library_altera.v
532,9 → 532,9
reg dff;
always @ (posedge clk or posedge rst)
if (rst)
{dff,q} <= 2'b00;
{q,dff} <= 2'b00;
else
{dff,q} <= {d,dff};
{q,dff} <= {dff,d};
endmodule
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;
557,7 → 557,7
.clk(clk_dst),
.rst(rst_dst));
vl_toggle2pulse t2p0 (
.d(take_it_sync),
.d(take_it_tg_sync),
.pl(take_it_pl),
.clk(clk_dst),
.rst(rst_dst));
573,7 → 573,7
.clk(clk_src),
.rst(rst_src));
vl_toggle2pulse t2p1 (
.d(take_it_grant_tg_sync),
.d(got_it_tg_sync),
.pl(got_it_pl),
.clk(clk_src),
.rst(rst_src));
1397,6 → 1397,7
parameter data_width = 32;
parameter addr_width = 8;
parameter mem_size = 1<<addr_width;
parameter debug = 0;
input [(data_width-1):0] d;
input [(addr_width-1):0] adr;
input we;
1403,15 → 1404,26
output reg [(data_width-1):0] q;
input clk;
reg [data_width-1:0] ram [mem_size-1:0];
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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)
if (we)
$display ("Value %h written at address %h : time %t", d, adr, $time);
end
endgenerate
always @ (posedge clk)
begin
if (we)
1437,14 → 1449,18
reg [data_width-1:0] ram [mem_size-1:0];
wire [data_width/8-1:0] cke;
`endif
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (memory_init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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
`ifdef SYSTEMVERILOG
always_ff@(posedge clk)
1496,16 → 1512,28
output [(data_width-1):0] q_b;
input clk_a, clk_b;
reg [(addr_width-1):0] adr_b_reg;
reg [data_width-1:0] ram [mem_szie-1:0] ;
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
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);
end
endgenerate
always @ (posedge clk_a)
if (we_a)
ram[adr_a] <= d_a;
1526,15 → 1554,27
input clk_a, clk_b;
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_szie-1:0] ;
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
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);
end
endgenerate
always @ (posedge clk_a)
begin
q_a <= ram[adr_a];
1544,6 → 1584,56
always @ (posedge clk_b)
q_b <= ram[adr_b];
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 );
parameter data_width = 32;
parameter addr_width = 8;
1559,15 → 1649,30
input clk_a, clk_b;
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_size-1:0] ;
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
parameter debug = 0;
generate
if (memory_init) 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];
1588,8 → 1693,9
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);
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 debug = 0;
input [(a_data_width-1):0] d_a;
input [(a_addr_width-1):0] adr_a;
input [(a_data_width/8-1):0] be_a;
1601,6 → 1707,16
input we_b;
output reg [(b_data_width-1):0] q_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
// use a multi-dimensional packed array
//to model individual bytes within the word
1608,15 → 1724,20
if (a_data_width==32 & b_data_width==32) begin : dpram_3232
logic [0:3][7:0] ram [0:mem_size-1] ;
initial
if (init)
if (memory_init==1)
$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)
begin
if(we_a) begin
if(be_a[3]) ram[adr_a][3] <= d_a[31:24];
if(be_a[2]) ram[adr_a][2] <= d_a[23:16];
if(be_a[1]) ram[adr_a][1] <= d_a[15:8];
if(be_a[0]) ram[adr_a][0] <= d_a[7:0];
if(be_a[3]) ram[adr_a][0] <= d_a[31:24];
if(be_a[2]) ram[adr_a][1] <= d_a[23:16];
if(be_a[1]) ram[adr_a][2] <= d_a[15:8];
if(be_a[0]) ram[adr_a][3] <= d_a[7:0];
end
end
always@(posedge clk_a)
1624,10 → 1745,10
always_ff@(posedge clk_b)
begin
if(we_b) begin
if(be_b[3]) ram[adr_b][3] <= d_b[31:24];
if(be_b[2]) ram[adr_b][2] <= d_b[23:16];
if(be_b[1]) ram[adr_b][1] <= d_b[15:8];
if(be_b[0]) ram[adr_b][0] <= d_b[7:0];
if(be_b[3]) ram[adr_b][0] <= d_b[31:24];
if(be_b[2]) ram[adr_b][1] <= d_b[23:16];
if(be_b[1]) ram[adr_b][2] <= d_b[15:8];
if(be_b[0]) ram[adr_b][3] <= d_b[7:0];
end
end
always@(posedge clk_b)
1638,8 → 1759,13
if (a_data_width==64 & b_data_width==64) begin : dpram_6464
logic [0:7][7:0] ram [0:mem_size-1] ;
initial
if (init)
if (memory_init==1)
$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)
begin
if(we_a) begin
1675,7 → 1801,7
generate
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
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 (
.d_a(d_a),
.q_a(q_a),
1690,7 → 1816,7
.we_b(we_b),
.clk_b(clk_b)
);
always_comb
always @ (adr_b[0] or temp)
if (adr_b[0])
q_b = temp[31:16];
else
1700,7 → 1826,7
generate
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
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 (
.d_a({d_a,d_a}),
.q_a(temp),
1715,7 → 1841,7
.we_b(we_b),
.clk_b(clk_b)
);
always_comb
always @ (adr_a[0] or temp)
if (adr_a[0])
q_a = temp[63:32];
else
2762,42 → 2888,36
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_o, wb_stall_o, wb_ack_o, wb_clk, wb_rst);
parameter dat_width = 32;
parameter adr_width = 8;
parameter dat_width = 32;
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 [adr_width-1:0] wb_adr_i;
input [dat_width/8-1:0] wb_sel_i;
input wb_we_i, wb_stb_i, wb_cyc_i;
output [dat_width-1:0] wb_dat_o;
reg [dat_width-1:0] wb_dat_o;
output wb_stall_o;
output wb_ack_o;
reg wb_ack_o;
input wb_clk, wb_rst;
wire [dat_width/8-1:0] cke;
generate
if (dat_width==32) begin
reg [7:0] ram3 [1<<(adr_width-2)-1:0];
reg [7:0] ram2 [1<<(adr_width-2)-1:0];
reg [7:0] ram1 [1<<(adr_width-2)-1:0];
reg [7:0] ram0 [1<<(adr_width-2)-1:0];
assign cke = wb_sel_i & {(dat_width/8){wb_we_i}};
always @ (posedge wb_clk)
begin
if (cke[3]) ram3[wb_adr_i[adr_width-1:2]] <= wb_dat_i[31:24];
if (cke[2]) ram2[wb_adr_i[adr_width-1:2]] <= wb_dat_i[23:16];
if (cke[1]) ram1[wb_adr_i[adr_width-1:2]] <= wb_dat_i[15:8];
if (cke[0]) ram0[wb_adr_i[adr_width-1:2]] <= wb_dat_i[7:0];
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
vl_ram_be # (
.data_width(dat_width),
.addr_width(adr_width),
.mem_size(mem_size),
.memory_init(memory_init),
.memory_file(memory_file))
ram0(
.d(wb_dat_i),
.adr(wb_adr_i),
.be(wb_sel_i),
.we(wb_we_i & wb_stb_i & wb_cyc_i),
.q(wb_dat_o),
.clk(wb_clk)
);
always @ (posedge wb_clk or posedge wb_rst)
if (wb_rst)
wb_ack_o <= 1'b0;
2905,18 → 3025,21
parameter dw_s = 32;
parameter aw_s = 24;
parameter dw_m = dw_s;
parameter aw_m = dw_s * aw_s / dw_m;
parameter max_burst_width = 4;
localparam aw_m = dw_s * aw_s / dw_m;
parameter wbs_max_burst_width = 4;
parameter async = 1; // wbs_clk != wbm_clk
parameter nr_of_ways = 1;
parameter aw_offset = 4; // 4 => 16 words per cache line
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;
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 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_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 [aw_s-1:0] wbs_adr_i; // dont include a1,a0
input [dw_s/8-1:0] wbs_sel_i;
2936,7 → 3059,7
input wbm_ack_i;
input wbm_stall_i;
input wbm_clk, wbm_rst;
wire dirty, valid;
wire valid, dirty, hit;
wire [aw_tag-1:0] tag;
wire tag_mem_we;
wire [aw_tag-1:0] wbs_adr_tag;
2954,21 → 3077,40
// wbm side
reg [aw_m-1:0] wbm_radr;
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;
reg [1:0] phase;
localparam wbm_wait = 2'b00;
localparam wbm_rd = 2'b10;
localparam wbm_wr = 2'b11;
reg [2:0] phase;
// phase = {we,stb,cyc}
localparam wbm_wait = 3'b000;
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 eoc = (wbs_cti_i==3'b000 | wbs_cti_i==3'b111) & wbs_ack_o;
vl_ram
# ( .data_width(aw_tag), .addr_width(aw_slot))
tag_mem ( .d(wbs_adr_slot), .adr(wbs_adr_tag), .we(done), .q(tag), .clk(wbs_clk));
assign valid = wbs_adr_tag == tag;
vl_wb_adr_inc # ( .adr_width(aw_s), .max_burst_width(max_burst_width)) adr_inc0 (
.cyc_i(wbs_cyc_i),
.stb_i(wbs_stb_i & (state==idle | (state==rw & valid))), // throttle depending on valid
generate
if (valid_mem==0) begin : no_valid_mem
assign valid = 1'b1;
end else begin : valid_mem_inst
vl_dpram_1r1w
# ( .data_width(1), .addr_width(aw_slot), .memory_init(2), .debug(debug))
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),
.bte_i(wbs_bte_i),
.adr_i(wbs_adr_i),
2975,12 → 3117,13
.we_i (wbs_we_i),
.ack_o(wbs_ack_o),
.adr_o(wbs_adr),
.clk(wbsa_clk),
.rst(wbsa_rst));
.clk(wbs_clk),
.rst(wbs_rst));
vl_dpram_be_2r2w
# ( .a_data_width(dw_s), .a_addr_width(aw_slot+aw_offset), .b_data_width(dw_m) )
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));
# ( .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),
.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)
if (wbs_rst)
state <= idle;
2990,16 → 3133,12
if (wbs_cyc_i)
state <= rdwr;
rdwr:
if (wbs_we_i & valid & eoc)
state <= idle;
else if (wbs_we_i & !valid)
state <= pull;
else if (!wbs_we_i & valid & eoc)
state <= idle;
else if (!wbs_we_i & !valid & !dirty)
state <= pull;
else if (!wbs_we_i & !valid & dirty)
state <= push;
casex ({valid, hit, dirty, eoc})
4'b0xxx: state <= pull;
4'b11x1: state <= idle;
4'b101x: state <= push;
4'b100x: state <= pull;
endcase
push:
if (done)
state <= rdwr;
3011,10 → 3150,10
// cdc
generate
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
else begin : nocdc
assign mem_alert = state==rdwr & !valid;
assign mem_alert = state==rdwr & (!valid | !hit);
assign done = mem_done;
end
endgenerate
3021,24 → 3160,21
// FSM generating a number of burts 4 cycles
// actual number depends on data width ratio
// nr_of_wbm_burst
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt0;
reg [nr_of_wbm_burst_width+wbm_burst_width-1:0] cnt1;
reg [wbm_burst_width-1:0] cnt_rw, cnt_ack;
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt0 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_rw <= {wbm_burst_width{1'b0}};
else
if (wbm_radr_cke)
cnt0 <= cnt0 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_radr_cke = wbm_cyc_o & wbm_stb_o & !wbm_stall_i;
assign wbm_radr = {wbs_adr_tag, tag, cnt0};
if (wbm_cyc_o & wbm_stb_o & !wbm_stall_i)
cnt_rw <= cnt_rw + 1;
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
cnt1 <= {nr_of_wbm_burst_width+wbm_burst_width{1'b0}};
cnt_ack <= {wbm_burst_width{1'b0}};
else
if (wbm_wadr_cke)
cnt1 <= cnt1 + 1;//(nr_of_wbm_burst_width+wbm_burst_width)1'd1;
assign wbm_wadr_cke = wbm_ack_i;
assign wbm_wadr = {wbs_adr_tag, wbs_adr_slot, cnt1};
if (wbm_ack_i)
cnt_ack <= cnt_ack + 1;
generate
if (nr_of_wbm_burst_width==0) begin : one_burst
always @ (posedge wbm_clk or posedge wbm_rst)
if (wbm_rst)
phase <= wbm_wait;
3046,20 → 3182,35
case (phase)
wbm_wait:
if (mem_alert)
phase <= state;
if (state==push)
phase <= wbm_wr;
else
phase <= wbm_rd;
wbm_wr:
if (&cnt1 & wbm_ack_i)
if (&cnt_rw)
phase <= wbm_wr_drain;
wbm_wr_drain:
if (&cnt_ack)
phase <= wbm_rd;
wbm_rd:
if (&cnt0 & wbm_ack_i)
phase <= idle;
if (&cnt_rw)
phase <= wbm_rd_drain;
wbm_rd_drain:
if (&cnt_ack)
phase <= wbm_wait;
default: phase <= wbm_wait;
endcase
assign wbm_adr_o = (phase==wbm_wr) ? {tag, wbs_adr_slot, cnt1} : {wbs_adr_tag, wbs_adr_slot, cnt1};
assign wbm_adr = (phase==wbm_wr) ? {wbs_adr_slot, cnt1} : {wbs_adr_slot, cnt1};
assign wbm_cti_o = (&cnt0 | &cnt1) ? 3'b111 : 3'b010;
assign mem_done = phase==wbm_rd_drain & (&cnt_ack) & wbm_ack_i;
end else begin : multiple_burst
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_we_o = phase==wbm_wr;
assign {wbm_we_o, wbm_stb_o, wbm_cyc_o} = phase;
endmodule
//////////////////////////////////////////////////////////////////////
//// ////
/rtl/verilog/defines.v
47,6 → 47,7
`define RAM_BE
`define DPRAM_1R1W
`define DPRAM_2R1W
`define DPRAM_1R2W
`define DPRAM_2R2W
`define DPRAM_BE_2R2W
`define FIFO_1R1W_FILL_LEVEL_SYNC
154,20 → 155,26
`endif
`endif
 
`ifdef WBB3_WBB4_CACHE
`ifndef RAM
`define RAM
`endif
`ifndef WB_ADR_INC
`define WB_ADR_INC
`endif
`ifndef dpram_be_2r2w
`define DPRAM_BE_2R2W
`endif
`ifndef CDC
`define CDC
`endif
`endif
`ifdef WBB3_WBB4_CACHE
`ifndef RAM
`define RAM
`endif
`ifndef WB_ADR_INC
`define WB_ADR_INC
`endif
`ifndef DPRAM_1R1W
`define DPRAM_1R1W
`endif
`ifndef DPRAM_1R2W
`define DPRAM_1R2W
`endif
`ifndef DPRAM_BE_2R2W
`define DPRAM_BE_2R2W
`endif
`ifndef CDC
`define CDC
`endif
`endif
`ifdef MULTS18X18
`ifndef MULTS
293,4 → 300,4
`endif
 
// size to width
`define SIZE2WIDTH_EXPR = (`SIZE2WIDTH==4) ? 2 : (`SIZE2WIDTH==8) ? 3 : (`SIZE2WIDTH==16) ? 4 : (`SIZE2WIDTH==32) ? 5 : (`SIZE2WIDTH==64) ? 6 : (`SIZE2WIDTH==128) ? 7 : 8;
`define SIZE2WIDTH_EXPR = (`SIZE2WIDTH==1) ? 0 : (`SIZE2WIDTH==2) ? 1 : (`SIZE2WIDTH==4) ? 2 : (`SIZE2WIDTH==8) ? 3 : (`SIZE2WIDTH==16) ? 4 : (`SIZE2WIDTH==32) ? 5 : (`SIZE2WIDTH==64) ? 6 : (`SIZE2WIDTH==128) ? 7 : 8;
/rtl/verilog/memories.v
74,6 → 74,7
parameter data_width = 32;
parameter addr_width = 8;
parameter mem_size = 1<<addr_width;
parameter debug = 0;
input [(data_width-1):0] d;
input [(addr_width-1):0] adr;
input we;
80,16 → 81,30
output reg [(data_width-1):0] q;
input clk;
reg [data_width-1:0] ram [mem_size-1:0];
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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)
if (we)
$display ("Value %h written at address %h : time %t", d, adr, $time);
end
endgenerate
always @ (posedge clk)
begin
if (we)
125,14 → 140,18
wire [data_width/8-1:0] cke;
//E2_endif
 
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (memory_init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
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
 
//E2_ifdef SYSTEMVERILOG
198,18 → 217,33
output [(data_width-1):0] q_b;
input clk_a, clk_b;
reg [(addr_width-1):0] adr_b_reg;
reg [data_width-1:0] ram [mem_szie-1:0] `SYN_NO_RW_CHECK;
reg [data_width-1:0] ram [mem_size-1:0] `SYN_NO_RW_CHECK;
 
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
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);
end
endgenerate
 
always @ (posedge clk_a)
if (we_a)
ram[adr_a] <= d_a;
238,16 → 272,31
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_szie-1:0] `SYN_NO_RW_CHECK;
 
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
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);
end
endgenerate
 
always @ (posedge clk_a)
begin
q_a <= ram[adr_a];
259,6 → 308,66
endmodule
`endif
 
`ifdef DPRAM_1R2W
`define MODULE dpram_1r2w
module `BASE`MODULE ( d_a, q_a, adr_a, we_a, clk_a, d_b, adr_b, we_b, clk_b );
`undef MODULE
 
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] `SYN_NO_RW_CHECK;
 
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
`endif
 
`ifdef DPRAM_2R2W
`define MODULE dpram_2r2w
module `BASE`MODULE ( d_a, q_a, adr_a, we_a, clk_a, d_b, q_b, adr_b, we_b, clk_b );
279,16 → 388,33
reg [(data_width-1):0] q_b;
reg [data_width-1:0] ram [mem_size-1:0] `SYN_NO_RW_CHECK;
 
parameter init = 0;
parameter memory_file = "vl_ram.vmem";
generate if (init) begin : init_mem
initial
begin
$readmemh(memory_file, ram);
end
end
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
parameter debug = 0;
generate
if (memory_init) 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];
317,8 → 443,9
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 init = 0;
parameter memory_init = 0;
parameter memory_file = "vl_ram.vmem";
parameter debug = 0;
input [(a_data_width-1):0] d_a;
input [(a_addr_width-1):0] adr_a;
332,6 → 459,18
output reg [(b_data_width-1):0] q_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
 
 
//E2_ifdef SYSTEMVERILOG
// use a multi-dimensional packed array
//to model individual bytes within the word
342,16 → 481,22
logic [0:3][7:0] ram [0:mem_size-1] `SYN_NO_RW_CHECK;
initial
if (init)
if (memory_init==1)
$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)
begin
if(we_a) begin
if(be_a[3]) ram[adr_a][3] <= d_a[31:24];
if(be_a[2]) ram[adr_a][2] <= d_a[23:16];
if(be_a[1]) ram[adr_a][1] <= d_a[15:8];
if(be_a[0]) ram[adr_a][0] <= d_a[7:0];
if(be_a[3]) ram[adr_a][0] <= d_a[31:24];
if(be_a[2]) ram[adr_a][1] <= d_a[23:16];
if(be_a[1]) ram[adr_a][2] <= d_a[15:8];
if(be_a[0]) ram[adr_a][3] <= d_a[7:0];
end
end
361,10 → 506,10
always_ff@(posedge clk_b)
begin
if(we_b) begin
if(be_b[3]) ram[adr_b][3] <= d_b[31:24];
if(be_b[2]) ram[adr_b][2] <= d_b[23:16];
if(be_b[1]) ram[adr_b][1] <= d_b[15:8];
if(be_b[0]) ram[adr_b][0] <= d_b[7:0];
if(be_b[3]) ram[adr_b][0] <= d_b[31:24];
if(be_b[2]) ram[adr_b][1] <= d_b[23:16];
if(be_b[1]) ram[adr_b][2] <= d_b[15:8];
if(be_b[0]) ram[adr_b][3] <= d_b[7:0];
end
end
380,8 → 525,14
logic [0:7][7:0] ram [0:mem_size-1] `SYN_NO_RW_CHECK;
initial
if (init)
if (memory_init==1)
$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)
begin
424,7 → 575,7
if (a_data_width==32 & b_data_width==16) begin : dpram_3216
logic [31:0] temp;
`define MODULE dpram_be_2r2w
`BASE`MODULE # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(init), .memory_file(memory_file))
`BASE`MODULE # (.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))
`undef MODULE
dpram6464 (
.d_a(d_a),
441,7 → 592,7
.clk_b(clk_b)
);
 
always_comb
always @ (adr_b[0] or temp)
if (adr_b[0])
q_b = temp[31:16];
else
454,7 → 605,7
if (a_data_width==32 & b_data_width==64) begin : dpram_3264
logic [63:0] temp;
`define MODULE dpram_be_2r2w
`BASE`MODULE # (.a_data_width(64), .b_data_width(64), .a_addr_width(a_addr_width), .mem_size(mem_size), .init(init), .memory_file(memory_file))
`BASE`MODULE # (.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))
`undef MODULE
dpram6464 (
.d_a({d_a,d_a}),
471,7 → 622,7
.clk_b(clk_b)
);
 
always_comb
always @ (adr_a[0] or temp)
if (adr_a[0])
q_a = temp[63:32];
else
/rtl/verilog/registers.v
517,9 → 517,9
reg dff;
always @ (posedge clk or posedge rst)
if (rst)
{dff,q} <= 2'b00;
{q,dff} <= 2'b00;
else
{dff,q} <= {d,dff};
{q,dff} <= {dff,d};
endmodule
`endif
 
555,7 → 555,7
`define MODULE toggle2pulse
`BASE`MODULE t2p0 (
`undef MODULE
.d(take_it_sync),
.d(take_it_tg_sync),
.pl(take_it_pl),
.clk(clk_dst),
.rst(rst_dst));
580,7 → 580,7
`define MODULE toggle2pulse
`BASE`MODULE t2p1 (
`undef MODULE
.d(take_it_grant_tg_sync),
.d(got_it_tg_sync),
.pl(got_it_pl),
.clk(clk_src),
.rst(rst_src));

powered by: WebSVN 2.1.0

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