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 100 to Rev 99
    Reverse comparison

Rev 100 → Rev 99

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

powered by: WebSVN 2.1.0

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