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

Subversion Repositories thor

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /thor/trunk
    from Rev 56 to Rev 57
    Reverse comparison

Rev 56 → Rev 57

/FT64v5/rtl/common/FT64_InsLength.v
25,6 → 25,7
// without the use of this module.
// ============================================================================
//
`include "FT64_config.vh"
`include "FT64_defines.vh"
 
module FT64_InsLength(ins, len);
32,9 → 33,11
output reg [2:0] len;
 
always @*
`ifdef SUPPORT_DCI
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
len <= 3'd2;
else
`endif
case(ins[7:6])
2'd0: len <= 3'd4;
2'd1: len <= 3'd6;
/FT64v5/rtl/common/FT64_cache.v
740,16 → 740,18
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
 
module FT64_dcache_tag(wclk, wr, wadr, rclk, radr, hit0, hit1);
module FT64_dcache_tag(wclk, wr, wadr, rclk, radr, whit, hit0, hit1);
input wclk;
input wr;
input [37:0] wadr;
input rclk;
input [37:0] radr;
output reg whit;
output reg hit0;
output reg hit1;
 
wire [31:0] tago0, tago1;
wire [31:0] wtago;
wire [37:0] radrp8 = radr + 32'd32;
 
FT64_dcache_tag2 u1 (
758,6 → 760,7
.wea(wr), // input wire [0 : 0] wea
.addra(wadr[13:5]), // input wire [8 : 0] addra
.dina(wadr[37:14]), // input wire [31 : 0] dina
.douta(wtago),
.clkb(rclk), // input wire clkb
.web(1'b0),
.dinb(32'd0),
784,6 → 787,8
hit0 <= tago0[23:0]==radr[37:14];
always @(posedge rclk)
hit1 <= tago1[23:0]==radrp8[37:14];
always @(posedge wclk)
whit <= wtago[23:0]==wadr[37:14];
 
endmodule
 
790,12 → 795,13
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
 
module FT64_dcache(rst, wclk, wr, sel, wadr, i, li, rclk, rdsize, radr, o, lo, hit, hit0, hit1);
module FT64_dcache(rst, wclk, wr, sel, wadr, whit, i, li, rclk, rdsize, radr, o, lo, hit, hit0, hit1);
input rst;
input wclk;
input wr;
input [7:0] sel;
input [37:0] wadr;
output whit;
input [63:0] i;
input [255:0] li; // line input
input rclk;
849,6 → 855,7
.wadr(wadr),
.rclk(rclk),
.radr(radr),
.whit(whit),
.hit0(hit0a),
.hit1(hit1a)
);
/FT64v5/rtl/common/FT64_config.vh
25,6 → 25,7
`define SIM 1'b1
//`define SUPPORT_SMT 1'b1
`define SUPPORT_VECTOR 1'b1
//`define SUPPORT_DCI 1'b1 // dynamically compressed instructions
//`define DEBUG_LOGIC 1'b1
 
`define AMSB 31
36,7 → 37,7
//`define SUPPORT_DBG 1'b1
`define FULL_ISSUE_LOGIC 1'b1
 
`define WAYS 2 // number of ways parallel (not working yet)
`define WAYS 2 // number of ways parallel (1-3 3 not working yet)
`define NUM_IDU 2 // number of instruction decode units (1-3)
`define NUM_ALU 2 // number of ALU's (1-2)
`define NUM_MEM 2 // number of memory queues (1-3)
/FT64v5/rtl/common/FT64_idecoder.v
942,9 → 942,11
bus <= 144'h0;
bus[`IB_CONST] <= instr[6]==1'b1 ? {{34{instr[47]}},instr[47:18]} :
{{50{instr[31]}},instr[31:18]};
`ifdef SUPPORT_DCI
if (instr[`INSTRUCTION_OP]==`CMPRSSD)
bus[`IB_LN] <= 3'd2;
else
`endif
case(instr[7:6])
2'b00: bus[`IB_LN] <= 3'd4;
2'b01: bus[`IB_LN] <= 3'd6;
/FT64v5/rtl/twoway/FT64.v
123,30 → 123,39
 
wire dc_ack;
wire acki = ack_i|dc_ack;
wire [RBIT:0] Ra0, Ra1;
wire [RBIT:0] Rb0, Rb1;
wire [RBIT:0] Rc0, Rc1;
wire [RBIT:0] Rt0, Rt1;
wire [RBIT:0] Ra0, Ra1, Ra2;
wire [RBIT:0] Rb0, Rb1, Rb2;
wire [RBIT:0] Rc0, Rc1, Rc2;
wire [RBIT:0] Rt0, Rt1, Rt2;
wire [63:0] rfoa0,rfob0,rfoc0,rfoc0a;
wire [63:0] rfoa1,rfob1,rfoc1,rfoc1a;
wire [63:0] rfoa2,rfob2,rfoc2,rfoc2a;
`ifdef SUPPORT_SMT
wire [7:0] Ra0s = {Ra0[7:0]};
wire [7:0] Ra1s = {Ra1[7:0]};
wire [7:0] Ra2s = {Ra2[7:0]};
wire [7:0] Rb0s = {Rb0[7:0]};
wire [7:0] Rb1s = {Rb1[7:0]};
wire [7:0] Rb2s = {Rb2[7:0]};
wire [7:0] Rc0s = {Rc0[7:0]};
wire [7:0] Rc1s = {Rc1[7:0]};
wire [7:0] Rc2s = {Rc2[7:0]};
wire [7:0] Rt0s = {Rt0[7:0]};
wire [7:0] Rt1s = {Rt1[7:0]};
wire [7:0] Rt2s = {Rt2[7:0]};
`else
wire [6:0] Ra0s = {Ra0[7],Ra0[5:0]};
wire [6:0] Ra1s = {Ra1[7],Ra1[5:0]};
wire [6:0] Ra2s = {Ra2[7],Ra2[5:0]};
wire [6:0] Rb0s = {Rb0[7],Rb0[5:0]};
wire [6:0] Rb1s = {Rb1[7],Rb1[5:0]};
wire [6:0] Rb2s = {Rb2[7],Rb2[5:0]};
wire [6:0] Rc0s = {Rc0[7],Rc0[5:0]};
wire [6:0] Rc1s = {Rc1[7],Rc1[5:0]};
wire [6:0] Rc2s = {Rc2[7],Rc2[5:0]};
wire [6:0] Rt0s = {Rt0[7],Rt0[5:0]};
wire [6:0] Rt1s = {Rt1[7],Rt1[5:0]};
wire [6:0] Rt2s = {Rt2[7],Rt2[5:0]};
/*
wire [5:0] Ra0s = {Ra0[5:0]};
wire [5:0] Ra1s = {Ra1[5:0]};
184,8 → 193,8
reg exvq;
 
// Vector
reg [5:0] vqe0, vqe1; // vector element being queued
reg [5:0] vqet0, vqet1;
reg [5:0] vqe0, vqe1, vqe2; // vector element being queued
reg [5:0] vqet0, vqet1, vqet2;
reg [7:0] vl; // vector length
reg [63:0] vm [0:7]; // vector mask registers
reg [1:0] m2;
393,12 → 402,14
// that would be four bits minimum (count 0 to 8).
reg [31:0] seq_num;
reg [31:0] seq_num1;
reg [31:0] seq_num2;
wire [63:0] rdat0,rdat1,rdat2;
reg [63:0] xdati;
 
reg canq1, canq2;
reg canq1, canq2, canq3;
reg queued1;
reg queued2;
reg queued3;
reg queuedNop;
 
reg [47:0] codebuf[0:63];
565,6 → 576,14
wire fetchbuf1_mem;
wire fetchbuf1_memld;
wire fetchbuf1_rfw;
wire [47:0] fetchbuf2_instr;
wire [2:0] fetchbuf2_insln;
wire [`ABITS] fetchbuf2_pc;
wire fetchbuf2_v;
wire fetchbuf2_thrd;
wire fetchbuf2_mem;
wire fetchbuf2_memld;
wire fetchbuf2_rfw;
 
wire [47:0] fetchbufA_instr;
wire [`ABITS] fetchbufA_pc;
578,6 → 597,12
wire [47:0] fetchbufD_instr;
wire [`ABITS] fetchbufD_pc;
wire fetchbufD_v;
wire [47:0] fetchbufE_instr;
wire [`ABITS] fetchbufE_pc;
wire fetchbufE_v;
wire [47:0] fetchbufF_instr;
wire [`ABITS] fetchbufF_pc;
wire fetchbufF_v;
 
//reg did_branchback0;
//reg did_branchback1;
891,7 → 916,9
wire [287:0] L2_dato;
reg L2_xsel;
 
FT64_regfile2w6r_oc #(.RBIT(RBIT)) urf1
generate begin : gRegfileInst
if (`WAYS > 2) begin : gb1
FT64_regfile2w9r_oc #(.RBIT(RBIT)) urf1
(
.clk(clk),
.clk4x(clk4x),
907,12 → 934,49
.ra0(Ra0),
.ra1(Rb0),
.ra2(Rc0),
.o0(rfoa0),
.o1(rfob0),
.o2(rfoc0a),
.ra3(Ra1),
.ra4(Rb1),
.ra5(Rc1),
.o3(rfoa1),
.o4(rfob1),
.o5(rfoc1a),
.ra6(Ra2),
.ra7(Rb2),
.ra8(Rc2),
.o6(rfoa2),
.o7(rfob2),
.o8(rfoc2a)
);
assign rfoc0 = Rc0[11:6]==6'h3F ? vm[Rc0[2:0]] : rfoc0a;
assign rfoc1 = Rc1[11:6]==6'h3F ? vm[Rc1[2:0]] : rfoc1a;
assign rfoc2 = Rc2[11:6]==6'h3F ? vm[Rc2[2:0]] : rfoc2a;
end
else if (`WAYS > 1) begin : gb1
FT64_regfile2w6r_oc #(.RBIT(RBIT)) urf1
(
.clk(clk),
.clk4x(clk4x),
.wr0(commit0_v),
.wr1(commit1_v),
.we0(commit0_we),
.we1(commit1_we),
.wa0(commit0_tgt),
.wa1(commit1_tgt),
.i0(commit0_bus),
.i1(commit1_bus),
.rclk(~clk),
.ra0(Ra0),
.ra1(Rb0),
.ra2(Rc0),
.o0(rfoa0),
.o1(rfob0),
.o2(rfoc0a),
.ra3(Ra1),
.ra4(Rb1),
.ra5(Rc1),
.o3(rfoa1),
.o4(rfob1),
.o5(rfoc1a)
919,12 → 983,35
);
assign rfoc0 = Rc0[11:6]==6'h3F ? vm[Rc0[2:0]] : rfoc0a;
assign rfoc1 = Rc1[11:6]==6'h3F ? vm[Rc1[2:0]] : rfoc1a;
end
else begin : gb1
FT64_regfile1w3r_oc #(.RBIT(RBIT)) urf1
(
.clk(clk),
.wr0(commit0_v),
.we0(commit0_we),
.wa0(commit0_tgt),
.i0(commit0_bus),
.rclk(~clk),
.ra0(Ra0),
.ra1(Rb0),
.ra2(Rc0),
.o0(rfoa0),
.o1(rfob0),
.o2(rfoc0a)
);
end
assign rfoc0 = Rc0[11:6]==6'h3F ? vm[Rc0[2:0]] : rfoc0a;
end
endgenerate
 
function [3:0] fnInsLength;
input [47:0] ins;
`ifdef SUPPORT_DCI
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
fnInsLength = 4'd2;
else
`endif
case(ins[7:6])
2'd0: fnInsLength = 4'd4;
2'd1: fnInsLength = 4'd6;
1032,26 → 1119,34
wire predict_taken;
wire predict_taken0;
wire predict_taken1;
wire predict_taken2;
wire predict_takenA;
wire predict_takenB;
wire predict_takenC;
wire predict_takenD;
wire predict_takenE;
wire predict_takenF;
wire predict_takenA1;
wire predict_takenB1;
wire predict_takenC1;
wire predict_takenD1;
 
wire [`ABITS] btgtA, btgtB, btgtC, btgtD;
wire [`ABITS] btgtA, btgtB, btgtC, btgtD, btgtE, btgtF;
wire btbwr0 = iqentry_v[head0] && iqentry_done[head0] &&
(
iqentry_jal[head0] ||
iqentry_brk[head0] ||
iqentry_rti[head0]);
generate begin: gbtbvar
if (`WAYS > 1) begin
wire btbwr1 = iqentry_v[head1] && iqentry_done[head1] &&
(
iqentry_jal[head1] ||
iqentry_brk[head1] ||
iqentry_rti[head1]);
end
end
endgenerate
 
wire fcu_clk;
`ifdef FCU_ENH
1064,6 → 1159,8
`endif
assign fcu_clk = clk_i;
 
generate begin: gBTBInst
if (`WAYS > 2) begin
`ifdef FCU_ENH
FT64_BTB ubtb1
(
1082,10 → 1179,16
.btgtC(btgtC),
.pcD(fetchbufD_pc),
.btgtD(btgtD),
.pcE(fetchbufE_pc),
.btgtE(btgtE),
.pcF(fetchbufF_pc),
.btgtF(btgtF),
.npcA(BRKPC),
.npcB(BRKPC),
.npcC(BRKPC),
.npcD(BRKPC)
.npcD(BRKPC),
.npcE(BRKPC),
.npcF(BRKPC)
);
`else
// Branch tergets are picked up by fetchbuf logic and need to be present.
1095,8 → 1198,93
assign btgtB = RSTPC;
assign btgtC = RSTPC;
assign btgtD = RSTPC;
assign btgtE = RSTPC;
assign btgtF = RSTPC;
`endif
end
else if (`WAYS > 1) begin
`ifdef FCU_ENH
FT64_BTB ubtb1
(
.rst(rst),
.wclk(fcu_clk),
.wr(btbwr0 | btbwr1),
.wadr(btbwr0 ? iqentry_pc[head0] : iqentry_pc[head1]),
.wdat(btbwr0 ? iqentry_a0[head0] : iqentry_a0[head1]),
.valid(btbwr0 ? iqentry_bt[head0] & iqentry_v[head0] : iqentry_bt[head1] & iqentry_v[head1]),
.rclk(~clk),
.pcA(fetchbufA_pc),
.btgtA(btgtA),
.pcB(fetchbufB_pc),
.btgtB(btgtB),
.pcC(fetchbufC_pc),
.btgtC(btgtC),
.pcD(fetchbufD_pc),
.btgtD(btgtD),
.pcE(32'd0),
.btgtE(),
.pcF(32'd0),
.btgtF(),
.npcA(BRKPC),
.npcB(BRKPC),
.npcC(BRKPC),
.npcD(BRKPC),
.npcE(BRKPC),
.npcF(BRKPC)
);
`else
// Branch tergets are picked up by fetchbuf logic and need to be present.
// Without a target predictor they are just set to the reset address.
// This virtually guarentees a miss.
assign btgtA = RSTPC;
assign btgtB = RSTPC;
assign btgtC = RSTPC;
assign btgtD = RSTPC;
`endif
end
else begin
`ifdef FCU_ENH
FT64_BTB ubtb1
(
.rst(rst),
.wclk(fcu_clk),
.wr(btbwr0),
.wadr(iqentry_pc[head0]),
.wdat(iqentry_a0[head0]),
.valid(iqentry_bt[head0] & iqentry_v[head0]),
.rclk(~clk),
.pcA(fetchbufA_pc),
.btgtA(btgtA),
.pcB(fetchbufB_pc),
.btgtB(btgtB),
.pcC(32'd0),
.btgtC(),
.pcD(32'd0),
.btgtD(),
.pcE(32'd0),
.btgtE(),
.pcF(32'd0),
.btgtF(),
.npcA(BRKPC),
.npcB(BRKPC),
.npcC(BRKPC),
.npcD(BRKPC),
.npcE(BRKPC),
.npcF(BRKPC)
);
`else
// Branch tergets are picked up by fetchbuf logic and need to be present.
// Without a target predictor they are just set to the reset address.
// This virtually guarentees a miss.
assign btgtA = RSTPC;
assign btgtB = RSTPC;
`endif
end
end
endgenerate
 
generate begin: gBPInst
if (`WAYS > 2) begin
`ifdef FCU_ENH
FT64_BranchPredictor ubp1
(
1109,6 → 1297,8
.pcB(fetchbufB_pc),
.pcC(fetchbufC_pc),
.pcD(fetchbufD_pc),
.pcE(fetchbufE_pc),
.pcF(fetchbufF_pc),
.xpc0(iqentry_pc[head0]),
.xpc1(iqentry_pc[head1]),
.takb0(commit0_v & iqentry_takb[head0]),
1116,7 → 1306,9
.predict_takenA(predict_takenA),
.predict_takenB(predict_takenB),
.predict_takenC(predict_takenC),
.predict_takenD(predict_takenD)
.predict_takenD(predict_takenD),
.predict_takenE(predict_takenE),
.predict_takenF(predict_takenF)
);
`else
// Predict based on sign of displacement
1124,7 → 1316,78
assign predict_takenB = fetchbufB_instr[31];
assign predict_takenC = fetchbufC_instr[31];
assign predict_takenD = fetchbufD_instr[31];
assign predict_takenE = fetchbufE_instr[31];
assign predict_takenF = fetchbufF_instr[31];
`endif
end
else if (`WAYS > 1) begin
`ifdef FCU_ENH
FT64_BranchPredictor ubp1
(
.rst(rst),
.clk(fcu_clk),
.en(bpe),
.xisBranch0(iqentry_br[head0] & commit0_v),
.xisBranch1(iqentry_br[head1] & commit1_v),
.pcA(fetchbufA_pc),
.pcB(fetchbufB_pc),
.pcC(fetchbufC_pc),
.pcD(fetchbufD_pc),
.pcE(32'd0),
.pcF(32'd0),
.xpc0(iqentry_pc[head0]),
.xpc1(iqentry_pc[head1]),
.takb0(commit0_v & iqentry_takb[head0]),
.takb1(commit1_v & iqentry_takb[head1]),
.predict_takenA(predict_takenA),
.predict_takenB(predict_takenB),
.predict_takenC(predict_takenC),
.predict_takenD(predict_takenD),
.predict_takenE(),
.predict_takenF()
);
`else
// Predict based on sign of displacement
assign predict_takenA = fetchbufA_instr[31];
assign predict_takenB = fetchbufB_instr[31];
assign predict_takenC = fetchbufC_instr[31];
assign predict_takenD = fetchbufD_instr[31];
`endif
end
else begin
`ifdef FCU_ENH
FT64_BranchPredictor ubp1
(
.rst(rst),
.clk(fcu_clk),
.en(bpe),
.xisBranch0(iqentry_br[head0] & commit0_v),
.xisBranch1(1'b0),
.pcA(fetchbufA_pc),
.pcB(fetchbufB_pc),
.pcC(32'd0),
.pcD(32'd0),
.pcE(32'd0),
.pcF(32'd0),
.xpc0(iqentry_pc[head0]),
.xpc1(32'd0),
.takb0(commit0_v & iqentry_takb[head0]),
.takb1(1'b0),
.predict_takenA(predict_takenA),
.predict_takenB(predict_takenB),
.predict_takenC(),
.predict_takenD(),
.predict_takenE(),
.predict_takenF()
);
`else
// Predict based on sign of displacement
assign predict_takenA = fetchbufA_instr[31];
assign predict_takenB = fetchbufB_instr[31];
`endif
end
end
endgenerate
 
//-----------------------------------------------------------------------------
// Debug
1416,6 → 1679,7
reg preload;
reg [1:0] dccnt;
wire dhit0, dhit1, dhit2;
wire dhit0a, dhit1a, dhit2a;
wire dhit00, dhit10, dhit20;
wire dhit01, dhit11, dhit21;
reg [`ABITS] dc_wadr;
1422,13 → 1686,37
reg [63:0] dc_wdat;
reg isStore;
 
// If the data is in the write buffer, give the buffer a chance to
// write out the data before trying to load from the cache.
reg wb_hit0, wb_hit1, wb_hit2;
always @*
begin
wb_hit0 <= FALSE;
wb_hit1 <= FALSE;
wb_hit2 <= FALSE;
for (n = 0; n < `WB_DEPTH; n = n + 1) begin
if (wb_v[n] && wb_addr[n][31:3]==dram0_addr[31:3])
wb_hit0 <= TRUE;
if (`NUM_MEM > 1 && wb_addr[n][31:3]==dram1_addr[31:3])
wb_hit1 <= TRUE;
if (`NUM_MEM > 2 && wb_addr[n][31:3]==dram2_addr[31:3])
wb_hit2 <= TRUE;
end
end
 
assign dhit0 = dhit0a & !wb_hit0;
assign dhit1 = dhit1a & !wb_hit1;
assign dhit2 = dhit2a & !wb_hit2;
wire whit0, whit1, whit2;
 
FT64_dcache udc0
(
.rst(rst),
.wclk(clk),
.wr((bstate==B2d && ack_i)||((bstate==B1||(bstate==B19 && isStore)) && dhit0)),
.wr((bstate==B2d && ack_i)||((bstate==B1||(bstate==B19 && isStore)) && whit0)),
.sel(sel_o),
.wadr({pcr[5:0],adr_o}),
.whit(whit0),
.i(bstate==B2d ? dat_i : dat_o),
.rclk(clk),
.rdsize(dram0_memsize),
1435,7 → 1723,7
.radr({pcr[5:0],dram0_addr}),
.o(dc0_out),
.hit(),
.hit0(dhit0),
.hit0(dhit0a),
.hit1()
);
generate begin : gDCacheInst
1444,9 → 1732,10
(
.rst(rst),
.wclk(clk),
.wr((bstate==B2d && ack_i)||((bstate==B1||(bstate==B19 && isStore)) && dhit1)),
.wr((bstate==B2d && ack_i)||((bstate==B1||(bstate==B19 && isStore)) && whit1)),
.sel(sel_o),
.wadr({pcr[5:0],adr_o}),
.whit(whit1),
.i(bstate==B2d ? dat_i : dat_o),
.rclk(clk),
.rdsize(dram1_memsize),
1453,7 → 1742,7
.radr({pcr[5:0],dram1_addr}),
.o(dc1_out),
.hit(),
.hit0(dhit1),
.hit0(dhit1a),
.hit1()
);
end
1462,9 → 1751,10
(
.rst(rst),
.wclk(clk),
.wr((bstate==B2d && ack_i)||((bstate==B1||(bstate==B19 && isStore)) && dhit2)),
.wr((bstate==B2d && ack_i)||((bstate==B1||(bstate==B19 && isStore)) && whit2)),
.sel(sel_o),
.wadr({pcr[5:0],adr_o}),
.whit(whit2),
.i(bstate==B2d ? dat_i : dat_o),
.rclk(clk),
.rdsize(dram2_memsize),
1471,7 → 1761,7
.radr({pcr[5:0],dram2_addr}),
.o(dc2_out),
.hit(),
.hit0(dhit2),
.hit0(dhit2a),
.hit1()
);
end
3014,10 → 3304,113
assign fetchbuf0_memld = IsMem(fetchbuf0_instr) & IsLoad(fetchbuf0_instr);
assign fetchbuf0_rfw = IsRFW(fetchbuf0_instr,vqe0,vl,fetchbuf0_thrd);
 
generate begin: gFetchbufDec
if (`WAYS > 1) begin
assign fetchbuf1_mem = IsMem(fetchbuf1_instr);
assign fetchbuf1_memld = IsMem(fetchbuf1_instr) & IsLoad(fetchbuf1_instr);
assign fetchbuf1_rfw = IsRFW(fetchbuf1_instr,vqe1,vl,fetchbuf1_thrd);
end
if (`WAYS > 2) begin
assign fetchbuf2_mem = IsMem(fetchbuf2_instr);
assign fetchbuf2_memld = IsMem(fetchbuf2_instr) & IsLoad(fetchbuf2_instr);
assign fetchbuf2_rfw = IsRFW(fetchbuf2_instr,vqe2,vl,fetchbuf2_thrd);
end
end
endgenerate
 
generate begin : gFetchbufInst
if (`WAYS > 2) begin : gb1
FT64_fetchbuf_x3 #(AMSB,RSTPC) ufb1
(
.rst(rst),
.clk4x(clk4x),
.clk(clk),
.fcu_clk(fcu_clk),
.cs_i(adr_o[31:16]==16'hFFFF),
.cyc_i(cyc_o),
.stb_i(stb_o),
.ack_o(dc_ack),
.we_i(we_o),
.adr_i(adr_o[15:0]),
.dat_i(dat_o[47:0]),
.cmpgrp(cr0[10:8]),
.freezePC(freezePC),
.regLR(regLR),
.thread_en(thread_en),
.insn0(insn0),
.insn1(insn1),
.insn1(insn2),
.phit(phit),
.threadx(threadx),
.branchmiss(branchmiss),
.misspc(misspc),
.branchmiss_thrd(branchmiss_thrd),
.predict_takenA(predict_takenA),
.predict_takenB(predict_takenB),
.predict_takenC(predict_takenC),
.predict_takenD(predict_takenD),
.predict_takenE(predict_takenE),
.predict_takenF(predict_takenF),
.predict_taken0(predict_taken0),
.predict_taken1(predict_taken1),
.predict_taken1(predict_taken2),
.queued1(queued1),
.queued2(queued2),
.queued2(queued3),
.queuedNop(queuedNop),
.pc0(pc0),
.pc1(pc1),
.fetchbuf(fetchbuf),
.fetchbufA_v(fetchbufA_v),
.fetchbufB_v(fetchbufB_v),
.fetchbufC_v(fetchbufC_v),
.fetchbufD_v(fetchbufD_v),
.fetchbufD_v(fetchbufE_v),
.fetchbufD_v(fetchbufF_v),
.fetchbufA_pc(fetchbufA_pc),
.fetchbufB_pc(fetchbufB_pc),
.fetchbufC_pc(fetchbufC_pc),
.fetchbufD_pc(fetchbufD_pc),
.fetchbufD_pc(fetchbufE_pc),
.fetchbufD_pc(fetchbufF_pc),
.fetchbufA_instr(fetchbufA_instr),
.fetchbufB_instr(fetchbufB_instr),
.fetchbufC_instr(fetchbufC_instr),
.fetchbufD_instr(fetchbufD_instr),
.fetchbufE_instr(fetchbufE_instr),
.fetchbufF_instr(fetchbufF_instr),
.fetchbuf0_instr(fetchbuf0_instr),
.fetchbuf1_instr(fetchbuf1_instr),
.fetchbuf0_thrd(fetchbuf0_thrd),
.fetchbuf1_thrd(fetchbuf1_thrd),
.fetchbuf2_thrd(fetchbuf2_thrd),
.fetchbuf0_pc(fetchbuf0_pc),
.fetchbuf1_pc(fetchbuf1_pc),
.fetchbuf2_pc(fetchbuf2_pc),
.fetchbuf0_v(fetchbuf0_v),
.fetchbuf1_v(fetchbuf1_v),
.fetchbuf2_v(fetchbuf2_v),
.fetchbuf0_insln(fetchbuf0_insln),
.fetchbuf1_insln(fetchbuf1_insln),
.fetchbuf2_insln(fetchbuf2_insln),
.codebuf0(codebuf[insn0[21:16]]),
.codebuf1(codebuf[insn1[21:16]]),
.codebuf2(codebuf[insn2[21:16]]),
.btgtA(btgtA),
.btgtB(btgtB),
.btgtC(btgtC),
.btgtD(btgtD),
.btgtE(btgtE),
.btgtF(btgtF),
.nop_fetchbuf(nop_fetchbuf),
.take_branch0(take_branch0),
.take_branch1(take_branch1),
.take_branch2(take_branch2),
.stompedRets(stompedOnRets),
.panic(fb_panic)
);
end
else if (`WAYS > 1) begin : gb1
FT64_fetchbuf #(AMSB,RSTPC) ufb1
(
.rst(rst),
3088,6 → 3481,61
.stompedRets(stompedOnRets),
.panic(fb_panic)
);
end
else begin : gb1
FT64_fetchbuf_x1 #(AMSB,RSTPC) ufb1
(
.rst(rst),
.clk4x(clk4x),
.clk(clk),
.fcu_clk(fcu_clk),
.cs_i(adr_o[31:16]==16'hFFFF),
.cyc_i(cyc_o),
.stb_i(stb_o),
.ack_o(dc_ack),
.we_i(we_o),
.adr_i(adr_o[15:0]),
.dat_i(dat_o[47:0]),
.cmpgrp(cr0[10:8]),
.freezePC(freezePC),
.regLR(regLR),
.thread_en(thread_en),
.insn0(insn0),
.phit(phit),
.threadx(threadx),
.branchmiss(branchmiss),
.misspc(misspc),
.branchmiss_thrd(branchmiss_thrd),
.predict_takenA(predict_takenA),
.predict_takenB(predict_takenB),
.predict_taken0(predict_taken0),
.queued1(queued1),
.queuedNop(queuedNop),
.pc0(pc0),
.fetchbuf(fetchbuf),
.fetchbufA_v(fetchbufA_v),
.fetchbufB_v(fetchbufB_v),
.fetchbufA_pc(fetchbufA_pc),
.fetchbufB_pc(fetchbufB_pc),
.fetchbufA_instr(fetchbufA_instr),
.fetchbufB_instr(fetchbufB_instr),
.fetchbuf0_instr(fetchbuf0_instr),
.fetchbuf0_thrd(fetchbuf0_thrd),
.fetchbuf0_pc(fetchbuf0_pc),
.fetchbuf0_v(fetchbuf0_v),
.fetchbuf0_insln(fetchbuf0_insln),
.codebuf0(codebuf[insn0[21:16]]),
.btgtA(btgtA),
.btgtB(btgtB),
.nop_fetchbuf(nop_fetchbuf),
.take_branch0(take_branch0),
.stompedRets(stompedOnRets),
.panic(fb_panic)
);
assign fetchbuf1_v = `INV;
end
end
endgenerate
 
 
 
5597,6 → 6045,9
// Instruction decode output should only pulse once for a queue entry. We
// want the decode to be invalidated after a clock cycle so that it isn't
// inadvertently used to update the queue at a later point.
dramA_v <= `INV;
dramB_v <= `INV;
dramC_v <= `INV;
id1_vi <= `INV;
if (`NUM_IDU > 1)
id2_vi <= `INV;
7044,6 → 7495,7
dat_o <= wb_data[0];
ol_o <= wb_ol[0];
wbo_id <= wb_id[0];
isStore <= TRUE;
bstate <= wb_rmw[0] ? B12 : B1;
end
begin
7167,6 → 7619,7
adr_o <= dram0_addr;
dat_o <= fnDato(dram0_instr,dram0_data);
ol_o <= dram0_ol;
isStore <= TRUE;
bstate <= B1;
`else
if (wbptr<`WB_DEPTH-1) begin
7209,6 → 7662,7
adr_o <= dram1_addr;
dat_o <= fnDato(dram1_instr,dram1_data);
ol_o <= dram1_ol;
isStore <= TRUE;
bstate <= B1;
`else
if (wbptr<`WB_DEPTH-1) begin
7251,6 → 7705,7
adr_o <= dram2_addr;
dat_o <= fnDato(dram2_instr,dram2_data);
ol_o <= dram2_ol;
isStore <= TRUE;
bstate <= B1;
`else
if (wbptr<`WB_DEPTH-1) begin
7419,7 → 7874,6
cyc_o <= `LOW;
stb_o <= `LOW;
we_o <= `LOW;
sel_o <= 8'h00;
cr_o <= 1'b0;
// This isn't a good way of doing things; the state should be propagated
// to the commit stage, however since this is a store we know there will
7623,7 → 8077,6
cas <= dat_i;
cyc_o <= `LOW;
stb_o <= `LOW;
sel_o <= 8'h00;
case(bwhich)
2'b00: dram0 <= `DRAMREQ_READY;
2'b01: dram1 <= `DRAMREQ_READY;
7658,7 → 8111,6
else begin
cyc_o <= `LOW;
stb_o <= `LOW;
sel_o <= 8'h00;
sr_o <= `LOW;
xdati <= dat_i;
case(bwhich)
7693,7 → 8145,11
end
B17: bstate <= B18;
B18: bstate <= B19;
B19: if (~acki) begin bstate <= BIDLE; isStore <= `FALSE; end
B19: if (~acki) begin
sel_o <= 8'h00;
bstate <= BIDLE;
isStore <= `FALSE;
end
B20:
if (~ack_i) begin
stb_o <= `HIGH;
7823,10 → 8279,10
$display ("Regfile: %d", rgs);
for (n=0; n < 32; n=n+4) begin
$display("%d: %h %d %o %d: %h %d %o %d: %h %d %o %d: %h %d %o#",
n[4:0]+0, urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b00}], regIsValid[n+0], rf_source[n+0],
n[4:0]+1, urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b01}], regIsValid[n+1], rf_source[n+1],
n[4:0]+2, urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b10}], regIsValid[n+2], rf_source[n+2],
n[4:0]+3, urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b11}], regIsValid[n+3], rf_source[n+3]
n[4:0]+0, gRegfileInst.gb1.urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b00}], regIsValid[n+0], rf_source[n+0],
n[4:0]+1, gRegfileInst.gb1.urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b01}], regIsValid[n+1], rf_source[n+1],
n[4:0]+2, gRegfileInst.gb1.urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b10}], regIsValid[n+2], rf_source[n+2],
n[4:0]+3, gRegfileInst.gb1.urf1.urf10.mem[{rgs,1'b0,n[4:2],2'b11}], regIsValid[n+3], rf_source[n+3]
);
end
`endif
7834,10 → 8290,10
$display("Call Stack:");
for (n = 0; n < 16; n = n + 4)
$display("%c%d: %h %c%d: %h %c%d: %h %c%d: %h",
ufb1.ursb1.rasp==n+0 ?">" : " ", n[4:0]+0, ufb1.ursb1.ras[n+0],
ufb1.ursb1.rasp==n+1 ?">" : " ", n[4:0]+1, ufb1.ursb1.ras[n+1],
ufb1.ursb1.rasp==n+2 ?">" : " ", n[4:0]+2, ufb1.ursb1.ras[n+2],
ufb1.ursb1.rasp==n+3 ?">" : " ", n[4:0]+3, ufb1.ursb1.ras[n+3]
gFetchbufInst.gb1.ufb1.ursb1.rasp==n+0 ?">" : " ", n[4:0]+0, gFetchbufInst.gb1.ufb1.ursb1.ras[n+0],
gFetchbufInst.gb1.ufb1.ursb1.rasp==n+1 ?">" : " ", n[4:0]+1, gFetchbufInst.gb1.ufb1.ursb1.ras[n+1],
gFetchbufInst.gb1.ufb1.ursb1.rasp==n+2 ?">" : " ", n[4:0]+2, gFetchbufInst.gb1.ufb1.ursb1.ras[n+2],
gFetchbufInst.gb1.ufb1.ursb1.rasp==n+3 ?">" : " ", n[4:0]+3, gFetchbufInst.gb1.ufb1.ursb1.ras[n+3]
);
$display("\n");
`endif
7846,17 → 8302,25
// $display("%d %h", rasp+n[3:0], ras[rasp+n[3:0]]);
$display("TakeBr:%d #", take_branch);//, backpc);
$display("Insn%d: %h", 0, insn0);
if (`WAYS > 1)
if (`WAYS==1) begin
$display("%c%c A: %d %h %h #",
45, fetchbuf?45:62, fetchbufA_v, fetchbufA_instr, fetchbufA_pc);
$display("%c%c B: %d %h %h #",
45, fetchbuf?62:45, fetchbufB_v, fetchbufB_instr, fetchbufB_pc);
end
else if (`WAYS > 1) begin
$display("Insn%d: %h", 1, insn1);
$display("%c%c A: %d %h %h #",
45, fetchbuf?45:62, fetchbufA_v, fetchbufA_instr, fetchbufA_pc);
$display("%c%c B: %d %h %h #",
45, fetchbuf?45:62, fetchbufB_v, fetchbufB_instr, fetchbufB_pc);
$display("%c%c C: %d %h %h #",
45, fetchbuf?62:45, fetchbufC_v, fetchbufC_instr, fetchbufC_pc);
$display("%c%c D: %d %h %h #",
45, fetchbuf?62:45, fetchbufD_v, fetchbufD_instr, fetchbufD_pc);
 
end
else if (`WAYS > 2) begin
$display("%c%c C: %d %h %h #",
45, fetchbuf?62:45, fetchbufC_v, fetchbufC_instr, fetchbufC_pc);
$display("%c%c D: %d %h %h #",
45, fetchbuf?62:45, fetchbufD_v, fetchbufD_instr, fetchbufD_pc);
end
for (i=0; i<QENTRIES; i=i+1)
$display("%c%c %d: %c%c%c%c %d %d %c%c %c %c%h %d %o %h %h %h %d %o %h %d %o %h %d %o %d:%h %h %d#",
(i[`QBITS]==head0)?"C":".",
/FT64v5/rtl/twoway/FT64_BTB.v
9,8 → 9,9
//
// ============================================================================
//
module FT64_BTB(rst, wclk, wr, wadr, wdat, valid, rclk, pcA, btgtA, pcB, btgtB, pcC, btgtC, pcD, btgtD,
npcA, npcB, npcC, npcD);
module FT64_BTB(rst, wclk, wr, wadr, wdat, valid, rclk, pcA, btgtA, pcB, btgtB,
pcC, btgtC, pcD, btgtD, pcE, btgtE, pcF, btgtF,
npcA, npcB, npcC, npcD, npcE, npcF);
parameter AMSB = 31;
parameter RSTPC = 32'hFFFC0100;
input rst;
28,14 → 29,20
output [AMSB:0] btgtC;
input [AMSB:0] pcD;
output [AMSB:0] btgtD;
input [AMSB:0] pcE;
output [AMSB:0] btgtE;
input [AMSB:0] pcF;
output [AMSB:0] btgtF;
input [AMSB:0] npcA;
input [AMSB:0] npcB;
input [AMSB:0] npcC;
input [AMSB:0] npcD;
input [AMSB:0] npcE;
input [AMSB:0] npcF;
 
integer n;
reg [(AMSB+1)*2+1:0] mem [0:1023];
reg [9:0] radrA, radrB, radrC, radrD;
reg [9:0] radrA, radrB, radrC, radrD, radrE, radrF;
initial begin
for (n = 0; n < 1024; n = n + 1)
mem[n] <= RSTPC;
54,13 → 61,21
#1 radrC <= pcC[11:2];
always @(posedge rclk)
#1 radrD <= pcD[11:2];
always @(posedge rclk)
#1 radrE <= pcE[11:2];
always @(posedge rclk)
#1 radrF <= pcF[11:2];
wire hitA = mem[radrA][(AMSB+1)*2:AMSB+1]==pcA && mem[radrA][(AMSB+1)*2+1];
wire hitB = mem[radrB][(AMSB+1)*2:AMSB+1]==pcB && mem[radrB][(AMSB+1)*2+1];
wire hitC = mem[radrC][(AMSB+1)*2:AMSB+1]==pcC && mem[radrC][(AMSB+1)*2+1];
wire hitD = mem[radrD][(AMSB+1)*2:AMSB+1]==pcD && mem[radrD][(AMSB+1)*2+1];
wire hitE = mem[radrE][(AMSB+1)*2:AMSB+1]==pcE && mem[radrE][(AMSB+1)*2+1];
wire hitF = mem[radrF][(AMSB+1)*2:AMSB+1]==pcF && mem[radrF][(AMSB+1)*2+1];
assign btgtA = hitA ? mem[radrA][AMSB:0] : npcA;
assign btgtB = hitB ? mem[radrB][AMSB:0] : npcB;
assign btgtC = hitC ? mem[radrC][AMSB:0] : npcC;
assign btgtD = hitD ? mem[radrD][AMSB:0] : npcD;
assign btgtE = hitE ? mem[radrE][AMSB:0] : npcE;
assign btgtF = hitF ? mem[radrF][AMSB:0] : npcF;
 
endmodule
/FT64v5/rtl/twoway/FT64_BranchPredicator.v
26,8 → 26,9
//
module FT64_BranchPredictor(rst, clk, en,
xisBranch0, xisBranch1,
pcA, pcB, pcC, pcD, xpc0, xpc1, takb0, takb1,
predict_takenA, predict_takenB, predict_takenC, predict_takenD);
pcA, pcB, pcC, pcD, pcE, pcF, xpc0, xpc1, takb0, takb1,
predict_takenA, predict_takenB, predict_takenC, predict_takenD,
predict_takenE, predict_takenF);
parameter DBW=32;
input rst;
input clk;
38,6 → 39,8
input [DBW-1:0] pcB;
input [DBW-1:0] pcC;
input [DBW-1:0] pcD;
input [DBW-1:0] pcE;
input [DBW-1:0] pcF;
input [DBW-1:0] xpc0;
input [DBW-1:0] xpc1;
input takb0;
46,6 → 49,8
output predict_takenB;
output predict_takenC;
output predict_takenD;
output predict_takenE;
output predict_takenF;
 
integer n;
reg [31:0] pcs [0:31];
67,15 → 72,21
wire [8:0] bht_raB = {pcB[8:2],gbl_branch_hist[2:1]}; // read address (IF stage)
wire [8:0] bht_raC = {pcC[8:2],gbl_branch_hist[2:1]}; // read address (IF stage)
wire [8:0] bht_raD = {pcD[8:2],gbl_branch_hist[2:1]}; // read address (IF stage)
wire [8:0] bht_raE = {pcE[8:2],gbl_branch_hist[2:1]}; // read address (IF stage)
wire [8:0] bht_raF = {pcF[8:2],gbl_branch_hist[2:1]}; // read address (IF stage)
wire [1:0] bht_xbits = branch_history_table[bht_wa];
wire [1:0] bht_ibitsA = branch_history_table[bht_raA];
wire [1:0] bht_ibitsB = branch_history_table[bht_raB];
wire [1:0] bht_ibitsC = branch_history_table[bht_raC];
wire [1:0] bht_ibitsD = branch_history_table[bht_raD];
wire [1:0] bht_ibitsE = branch_history_table[bht_raE];
wire [1:0] bht_ibitsF = branch_history_table[bht_raF];
assign predict_takenA = (bht_ibitsA==2'd0 || bht_ibitsA==2'd1) && en;
assign predict_takenB = (bht_ibitsB==2'd0 || bht_ibitsB==2'd1) && en;
assign predict_takenC = (bht_ibitsC==2'd0 || bht_ibitsC==2'd1) && en;
assign predict_takenD = (bht_ibitsD==2'd0 || bht_ibitsD==2'd1) && en;
assign predict_takenE = (bht_ibitsE==2'd0 || bht_ibitsE==2'd1) && en;
assign predict_takenF = (bht_ibitsF==2'd0 || bht_ibitsF==2'd1) && en;
 
always @(posedge clk)
if (rst)
/FT64v5/rtl/twoway/FT64_fetchbuf.v
166,9 → 166,11
 
function [2:0] fnInsLength;
input [47:0] ins;
`ifdef SUPPORT_DCI
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
fnInsLength = 3'd2;
else
`endif
case(ins[7:6])
2'd0: fnInsLength = 3'd4;
2'd1: fnInsLength = 3'd6;
204,6 → 206,7
// Table of decompressed instructions.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
assign ack_o = cs_i & cyc_i & stb_i;
`ifdef SUPPORT_DCI
reg [47:0] DecompressTable [0:2047];
always @(posedge clk)
if (cs_i & cyc_i & stb_i & we_i)
210,6 → 213,7
DecompressTable[adr_i[12:3]] <= dat_i[47:0];
wire [47:0] expand0 = DecompressTable[{cmpgrp,insn0[15:8]}];
wire [47:0] expand1 = DecompressTable[{cmpgrp,insn1[15:8]}];
`endif
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
814,9 → 818,12
reg [2:0] insln0, insln1;
always @*
begin
`ifdef SUPPORT_DCI
if (insn0[5:0]==`CMPRSSD)
insln0 <= 3'd2;
else if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
else
`endif
if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
insln0 <= fnInsLength(codebuf0);
else
insln0 <= fnInsLength(insn0);
824,9 → 831,12
 
always @*
begin
`ifdef SUPPORT_DCI
if (insn1[5:0]==`CMPRSSD)
insln1 <= 3'd2;
else if (insn1[7:6]==2'b00 && insn1[`INSTRUCTION_OP]==`EXEC)
else
`endif
if (insn1[7:6]==2'b00 && insn1[`INSTRUCTION_OP]==`EXEC)
insln1 <= fnInsLength(codebuf1);
else
insln1 <= fnInsLength(insn1);
836,9 → 846,12
 
always @*
begin
`ifdef SUPPORT_DCI
if (insn0[5:0]==`CMPRSSD)
cinsn0 <= expand0;
else if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
else
`endif
if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
cinsn0 <= codebuf0;
else if (insn0[7])
cinsn0 <= xinsn0;
848,9 → 861,12
 
always @*
begin
`ifdef SUPPORT_DCI
if (insn1[5:0]==`CMPRSSD)
cinsn1 <= expand1;
else if (insn1[7:6]==2'b00 && insn1[`INSTRUCTION_OP]==`EXEC)
else
`endif
if (insn1[7:6]==2'b00 && insn1[`INSTRUCTION_OP]==`EXEC)
cinsn1 <= codebuf1;
else if (insn1[7])
cinsn1 <= xinsn1;
/FT64v5/rtl/twoway/FT64_fetchbuf_x1.v
0,0 → 1,441
// ============================================================================
// __
// \\__/ o\ (C) 2018 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// FT64_fetchbuf_x1.v
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
// ============================================================================
//
`include "FT64_config.vh"
`include "FT64_defines.vh"
 
// FETCH
//
// fetch exactly one instructions from memory into the fetch buffer
// unless either one of the buffers is still full, in which case we
// do nothing (kinda like alpha approach)
//
module FT64_fetchbuf_x1(rst, clk4x, clk, fcu_clk,
cs_i, cyc_i, stb_i, ack_o, we_i, adr_i, dat_i,
cmpgrp,
freezePC, thread_en,
regLR,
insn0, phit,
threadx,
branchmiss, misspc, branchmiss_thrd, predict_taken0,
predict_takenA, predict_takenB,
queued1, queuedNop,
pc0, fetchbuf, fetchbufA_v, fetchbufB_v,
fetchbufA_instr, fetchbufA_pc,
fetchbufB_instr, fetchbufB_pc,
fetchbuf0_instr, fetchbuf0_insln,
fetchbuf0_thrd,
fetchbuf0_pc,
fetchbuf0_v,
codebuf0,
btgtA, btgtB,
nop_fetchbuf,
take_branch0,
stompedRets,
panic
);
parameter AMSB = `AMSB;
parameter RSTPC = 32'hFFFC0100;
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
input rst;
input clk4x;
input clk;
input fcu_clk;
input cs_i;
input cyc_i;
input stb_i;
output ack_o;
input we_i;
input [15:0] adr_i;
input [47:0] dat_i;
input [2:0] cmpgrp;
input freezePC;
input thread_en;
input [4:0] regLR;
input [47:0] insn0;
input phit;
output threadx;
input branchmiss;
input [AMSB:0] misspc;
input branchmiss_thrd;
output predict_taken0;
input predict_takenA;
input predict_takenB;
input queued1;
input queuedNop;
output reg [AMSB:0] pc0;
output reg fetchbuf;
output reg fetchbufA_v;
output reg fetchbufB_v;
output fetchbuf0_thrd;
output reg [47:0] fetchbufA_instr;
output reg [47:0] fetchbufB_instr;
output reg [AMSB:0] fetchbufA_pc;
output reg [AMSB:0] fetchbufB_pc;
output [47:0] fetchbuf0_instr;
output [AMSB:0] fetchbuf0_pc;
output [2:0] fetchbuf0_insln;
output fetchbuf0_v;
input [47:0] codebuf0;
input [AMSB:0] btgtA;
input [AMSB:0] btgtB;
input [3:0] nop_fetchbuf;
output take_branch0;
input [3:0] stompedRets;
output reg [3:0] panic;
integer n;
 
//`include "FT64_decode.vh"
 
function IsBranch;
input [47:0] isn;
casex(isn[`INSTRUCTION_OP])
`Bcc: IsBranch = TRUE;
`BBc: IsBranch = TRUE;
`BEQI: IsBranch = TRUE;
`BCHK: IsBranch = TRUE;
default: IsBranch = FALSE;
endcase
endfunction
 
function IsJmp;
input [47:0] isn;
IsJmp = isn[`INSTRUCTION_OP]==`JMP;
endfunction
 
function IsCall;
input [47:0] isn;
IsCall = isn[`INSTRUCTION_OP]==`CALL;
endfunction
 
function IsRet;
input [47:0] isn;
IsRet = isn[`INSTRUCTION_OP]==`RET;
endfunction
 
function IsRTI;
input [47:0] isn;
IsRTI = isn[`INSTRUCTION_OP]==`R2 && isn[`INSTRUCTION_S2]==`RTI;
endfunction
 
function [2:0] fnInsLength;
input [47:0] ins;
`ifdef SUPPORT_DCI
if (ins[`INSTRUCTION_OP]==`CMPRSSD)
fnInsLength = 3'd2;
else
`endif
case(ins[7:6])
2'd0: fnInsLength = 3'd4;
2'd1: fnInsLength = 3'd6;
default: fnInsLength = 3'd2;
endcase
endfunction
 
wire [2:0] fetchbufA_inslen;
wire [2:0] fetchbufB_inslen;
FT64_InsLength uilA (fetchbufA_instr, fetchbufA_inslen);
FT64_InsLength uilB (fetchbufB_instr, fetchbufB_inslen);
 
wire [47:0] xinsn0;
 
FT64_iexpander ux1
(
.cinstr(insn0[15:0]),
.expand(xinsn0)
);
 
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Table of decompressed instructions.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
assign ack_o = cs_i & cyc_i & stb_i;
`ifdef SUPPORT_DCI
reg [47:0] DecompressTable [0:2047];
always @(posedge clk)
if (cs_i & cyc_i & stb_i & we_i)
DecompressTable[adr_i[12:3]] <= dat_i[47:0];
wire [47:0] expand0 = DecompressTable[{cmpgrp,insn0[15:8]}];
`endif
 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
reg thread;
reg stompedRet;
reg ret0Counted;
wire [AMSB:0] retpc0;
 
reg did_branchback0;
 
assign predict_taken0 = (fetchbuf==1'b0) ? predict_takenA : predict_takenB;
 
reg [AMSB:0] branch_pcA;
reg [AMSB:0] branch_pcB;
 
always @*
case(fetchbufA_instr[`INSTRUCTION_OP])
`RET: branch_pcA = retpc0;
`JMP,`CALL: branch_pcA = fetchbufA_instr[6] ? {fetchbufA_instr[39:8],1'b0} : {fetchbufA_pc[31:25],fetchbufA_instr[31:8],1'b0};
`R2: branch_pcA = btgtA; // RTI
`BRK,`JAL: branch_pcA = btgtA;
default: branch_pcA = fetchbufA_pc + {{20{fetchbufA_instr[31]}},fetchbufA_instr[31:21],1'b0} + fetchbufA_inslen;
endcase
 
always @*
case(fetchbufB_instr[`INSTRUCTION_OP])
`RET: branch_pcB = retpc0;
`JMP,`CALL: branch_pcB = fetchbufB_instr[6] ? {fetchbufB_instr[39:8],1'b0} : {fetchbufB_pc[31:25],fetchbufB_instr[31:8],1'b0};
`R2: branch_pcB = btgtB; // RTI
`BRK,`JAL: branch_pcB = btgtB;
default: branch_pcB = fetchbufB_pc + {{20{fetchbufB_instr[31]}},fetchbufB_instr[31:21],1'b0} + fetchbufB_inslen;
endcase
 
wire take_branchA = ({fetchbufA_v, IsBranch(fetchbufA_instr), predict_takenA} == {`VAL, `TRUE, `TRUE}) ||
((IsRet(fetchbufA_instr)||IsJmp(fetchbufA_instr)||IsCall(fetchbufA_instr)||
IsRTI(fetchbufA_instr)|| fetchbufA_instr[`INSTRUCTION_OP]==`BRK || fetchbufA_instr[`INSTRUCTION_OP]==`JAL) &&
fetchbufA_v);
wire take_branchB = ({fetchbufB_v, IsBranch(fetchbufB_instr), predict_takenB} == {`VAL, `TRUE, `TRUE}) ||
((IsRet(fetchbufB_instr)|IsJmp(fetchbufB_instr)|IsCall(fetchbufB_instr) ||
IsRTI(fetchbufB_instr)|| fetchbufB_instr[`INSTRUCTION_OP]==`BRK || fetchbufB_instr[`INSTRUCTION_OP]==`JAL) &&
fetchbufB_v);
 
wire take_branch = fetchbuf==1'b0 ? take_branchA : take_branchB;
assign take_branch0 = take_branch;
 
/*
always @*
begin
pc0 <= thread_en ? (fetchbuf ? pc0b : pc0a) : pc0a;
pc1 <= thread_en ? (fetchbuf ? pc1b : pc1a) : pc1a;
end
*/
assign threadx = fetchbuf;
 
`ifdef FCU_ENH
FT64_RSB #(AMSB) ursb1
(
.rst(rst),
.clk(fcu_clk),
.regLR(regLR),
.queued1(queued1),
.queued2(1'b0),
.fetchbuf0_v(fetchbuf0_v),
.fetchbuf0_pc(fetchbuf0_pc),
.fetchbuf0_instr(fetchbuf0_instr),
.fetchbuf1_v(1'b0),
.fetchbuf1_pc(RSTPC),
.fetchbuf1_instr(`NOP_INSN),
.stompedRets(stompedRets),
.stompedRet(stompedRet),
.pc(retpc0)
);
 
`else
assign retpc0 = RSTPC;
assign retpc1 = RSTPC;
`endif
 
wire peclk, neclk;
edge_det ued1 (.rst(rst), .clk(clk4x), .ce(1'b1), .i(clk), .pe(peclk), .ne(neclk), .ee());
 
always @(posedge clk)
if (rst) begin
pc0 <= RSTPC;
fetchbufA_v <= 0;
fetchbufB_v <= 0;
fetchbuf <= 0;
panic <= `PANIC_NONE;
end
else begin
did_branchback0 <= take_branch0;
 
begin
 
// On a branch miss with threading enabled all fectch buffers are
// invalidated even though the data in the fetch buffer would be valid
// for the thread that isn't in a branchmiss state. This is done to
// keep things simple. For the thread that doesn't miss the current
// data for the fetch buffer needs to be retrieved again, so the pc
// for that thread is assigned the current fetchbuf pc.
// For the thread that misses the pc is simply assigned the misspc.
if (branchmiss) begin
$display("***********");
$display("Branch miss");
$display("***********");
pc0 <= misspc;
fetchbufA_v <= `INV;
fetchbufB_v <= `INV;
fetchbuf <= 1'b0;
$display("********************");
$display("********************");
$display("********************");
$display("Branch miss");
$display("misspc=%h", misspc);
$display("********************");
$display("********************");
$display("********************");
end
else if (take_branch) begin
if (fetchbuf == 1'b0) case ({fetchbufA_v, fetchbufB_v})
2'b00: ; // do nothing
// 2'b01 : panic <= `PANIC_INVALIDFBSTATE;
2'b10:
begin
pc0 <= branch_pcA;
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
fetchbuf <= fetchbuf + (queued1|queuedNop);
end
2'b11:
begin
pc0 <= branch_pcA;
fetchbufA_v <= !(queued1|queuedNop); // if it can be queued, it will
fetchbufB_v <= `INV;
fetchbuf <= fetchbuf + (queued1|queuedNop);
end
default: ;
endcase
else case ({fetchbufB_v, fetchbufA_v})
2'b00: ; // do nothing
2'b10:
begin
pc0 <= branch_pcB;
fetchbufB_v <= !(queued1|queuedNop);
fetchbuf <= fetchbuf + (queued1|queuedNop);
end
2'b11:
begin
pc0 <= branch_pcB;
fetchbufB_v <= !(queued1|queuedNop);
fetchbufA_v <= `INV;
fetchbuf <= fetchbuf + (queued1|queuedNop);
end
default: ;
endcase
 
end // if branchback
 
else begin // there is no branchback in the system
// update fetchbufX_v and fetchbuf ... relatively simple, as
// there are no backwards branches in the mix
if (fetchbuf == 1'b0) case ({fetchbufA_v, (queued1|queuedNop)})
2'b00: ; // do nothing
2'b10: ;
2'b11: begin fetchbufA_v <= `INV; fetchbuf <= ~fetchbuf; end
default: panic <= `PANIC_INVALIDIQSTATE;
endcase
else case ({fetchbufB_v, (queued1|queuedNop)})
2'b00: ; // do nothing
2'b10: ;
2'b11: begin fetchbufB_v <= `INV; fetchbuf <= ~fetchbuf; end
default: panic <= `PANIC_INVALIDIQSTATE;
endcase
//
// get data iff the fetch buffers are empty
//
if (fetchbufA_v == `INV) begin
FetchA();
// fetchbuf steering logic correction
if (fetchbufB_v==`INV && phit)
fetchbuf <= 1'b0;
end
else if (fetchbufB_v == `INV)
FetchB();
end
//
// get data iff the fetch buffers are empty
//
if (fetchbufA_v == `INV && fetchbufB_v == `INV) begin
FetchA();
fetchbuf <= 1'b0;
end
end
// The fetchbuffer is invalidated at the end of a vector instruction
// queue.
if (nop_fetchbuf[0]) fetchbufA_v <= `INV;
if (nop_fetchbuf[1]) fetchbufB_v <= `INV;
end
 
assign fetchbuf0_instr = (fetchbuf == 1'b0) ? fetchbufA_instr : fetchbufB_instr;
assign fetchbuf0_insln = (fetchbuf == 1'b0) ? fetchbufA_inslen: fetchbufB_inslen;
assign fetchbuf0_v = (fetchbuf == 1'b0) ? fetchbufA_v : fetchbufB_v ;
assign fetchbuf0_pc = (fetchbuf == 1'b0) ? fetchbufA_pc : fetchbufB_pc ;
assign fetchbuf0_thrd = 1'b0;
 
reg [2:0] insln0;
always @*
begin
`ifdef SUPPORT_DCI
if (insn0[5:0]==`CMPRSSD)
insln0 <= 3'd2;
else
`endif
if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
insln0 <= fnInsLength(codebuf0);
else
insln0 <= fnInsLength(insn0);
end
 
reg [47:0] cinsn0;
 
always @*
begin
`ifdef SUPPORT_DCI
if (insn0[5:0]==`CMPRSSD)
cinsn0 <= expand0;
else
`endif
if (insn0[7:6]==2'b00 && insn0[`INSTRUCTION_OP]==`EXEC)
cinsn0 <= codebuf0;
else if (insn0[7])
cinsn0 <= xinsn0;
else
cinsn0 <= insn0;
end
 
task FetchA;
begin
fetchbufA_instr <= cinsn0;
fetchbufA_v <= `VAL;
fetchbufA_pc <= pc0;
if (phit && ~freezePC)
pc0 <= pc0 + insln0;
end
endtask
 
task FetchB;
begin
fetchbufB_instr <= cinsn0;
fetchbufB_v <= `VAL;
fetchbufB_pc <= pc0;
if (phit && ~freezePC)
pc0 <= pc0 + insln0;
end
endtask
 
endmodule
 
/FT64v5/rtl/twoway/FT64_regfile1w3r_oc.v
0,0 → 1,233
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2018 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//
// Register file with two write ports and six read ports.
// ============================================================================
//
`include "FT64_config.vh"
 
module FT64_regfileRam_sim(clka, ena, wea, addra, dina, clkb, enb, addrb, doutb);
parameter WID=64;
parameter RBIT = 11;
input clka;
input ena;
input [7:0] wea;
input [RBIT:0] addra;
input [WID-1:0] dina;
input clkb;
input enb;
input [RBIT:0] addrb;
output [WID-1:0] doutb;
 
integer n;
(* RAM_STYLE="BLOCK" *)
reg [64:0] mem [0:4095];
reg [RBIT:0] raddrb;
 
initial begin
for (n = 0; n < 4096; n = n + 1)
mem[n] = 0;
end
 
always @(posedge clka) if (ena & wea[0]) mem[addra][7:0] <= dina[7:0];
always @(posedge clka) if (ena & wea[1]) mem[addra][15:8] <= dina[15:8];
always @(posedge clka) if (ena & wea[2]) mem[addra][23:16] <= dina[23:16];
always @(posedge clka) if (ena & wea[3]) mem[addra][31:24] <= dina[31:24];
always @(posedge clka) if (ena & wea[4]) mem[addra][39:32] <= dina[39:32];
always @(posedge clka) if (ena & wea[5]) mem[addra][47:40] <= dina[47:40];
always @(posedge clka) if (ena & wea[6]) mem[addra][55:48] <= dina[55:48];
always @(posedge clka) if (ena & wea[7]) mem[addra][63:56] <= dina[63:56];
 
always @(posedge clkb)
raddrb <= addrb;
assign doutb = mem[raddrb];
endmodule
 
module FT64_regfile1w3r_oc(clk, wr0, we0, wa0, i0,
rclk, ra0, ra1, ra2, o0, o1, o2);
parameter WID=64;
parameter RBIT = 11;
input clk;
input wr0;
input [7:0] we0;
input [RBIT:0] wa0;
input [WID-1:0] i0;
input rclk;
input [RBIT:0] ra0;
input [RBIT:0] ra1;
input [RBIT:0] ra2;
output [WID-1:0] o0;
output [WID-1:0] o1;
output [WID-1:0] o2;
 
reg wr;
reg [RBIT:0] wa;
reg [WID-1:0] i;
reg [7:0] we;
wire [WID-1:0] o00, o01, o02;
 
integer n;
 
`ifdef SIM
FT64_regfileRam_sim urf10 (
.clka(clk),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra0),
.doutb(o00)
);
 
FT64_regfileRam_sim urf11 (
.clka(clk),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra1),
.doutb(o01)
);
 
FT64_regfileRam_sim urf12 (
.clka(clk),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra2),
.doutb(o02)
);
 
`else
FT64_regfileRam urf10 (
.clka(clk),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra0),
.dinb(64'h00),
.doutb(o00)
);
 
FT64_regfileRam urf11 (
.clka(clk),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra1),
.dinb(64'h00),
.doutb(o01)
);
 
FT64_regfileRam urf12 (
.clka(clk),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra2),
.dinb(64'h00),
.doutb(o02)
);
 
`endif
 
always @*
begin
wr <= wr0;
we <= we0;
wa <= wa0;
i <= i0;
end
 
assign o0[7:0] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[0] && (ra0==wa0)) ? i0[7:0] : o00[7:0];
assign o0[15:8] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[1] && (ra0==wa0)) ? i0[15:8] : o00[15:8];
assign o0[23:16] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[2] && (ra0==wa0)) ? i0[23:16] : o00[23:16];
assign o0[31:24] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[3] && (ra0==wa0)) ? i0[31:24] : o00[31:24];
assign o0[39:32] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[4] && (ra0==wa0)) ? i0[39:32] : o00[39:32];
assign o0[47:40] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[5] && (ra0==wa0)) ? i0[47:40] : o00[47:40];
assign o0[55:48] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[6] && (ra0==wa0)) ? i0[55:48] : o00[55:48];
assign o0[63:56] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[7] && (ra0==wa0)) ? i0[63:56] : o00[63:56];
 
assign o1[7:0] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[0] && (ra1==wa0)) ? i0[7:0] : o01[7:0];
assign o1[15:8] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[1] && (ra1==wa0)) ? i0[15:8] : o01[15:8];
assign o1[23:16] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[2] && (ra1==wa0)) ? i0[23:16] : o01[23:16];
assign o1[31:24] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[3] && (ra1==wa0)) ? i0[31:24] : o01[31:24];
assign o1[39:32] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[4] && (ra1==wa0)) ? i0[39:32] : o01[39:32];
assign o1[47:40] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[5] && (ra1==wa0)) ? i0[47:40] : o01[47:40];
assign o1[55:48] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[6] && (ra1==wa0)) ? i0[55:48] : o01[55:48];
assign o1[63:56] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[7] && (ra1==wa0)) ? i0[63:56] : o01[63:56];
 
assign o2[7:0] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[0] && (ra2==wa0)) ? i0[7:0] : o02[7:0];
assign o2[15:8] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[1] && (ra2==wa0)) ? i0[15:8] : o02[15:8];
assign o2[23:16] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[2] && (ra2==wa0)) ? i0[23:16] : o02[23:16];
assign o2[31:24] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[3] && (ra2==wa0)) ? i0[31:24] : o02[31:24];
assign o2[39:32] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[4] && (ra2==wa0)) ? i0[39:32] : o02[39:32];
assign o2[47:40] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[5] && (ra2==wa0)) ? i0[47:40] : o02[47:40];
assign o2[55:48] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[6] && (ra2==wa0)) ? i0[55:48] : o02[55:48];
assign o2[63:56] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr0 && we0[7] && (ra2==wa0)) ? i0[63:56] : o02[63:56];
 
endmodule
 
/FT64v5/rtl/twoway/FT64_regfile2w6r_oc.v
319,9 → 319,6
assign o0[55:48] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra0==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra0==wa0)) ? i0[55:48] : o00[55:48];
assign o0[55:48] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra0==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra0==wa0)) ? i0[55:48] : o00[55:48];
assign o0[63:56] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra0==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra0==wa0)) ? i0[63:56] : o00[63:56];
347,9 → 344,6
assign o1[55:48] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra1==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra1==wa0)) ? i0[55:48] : o01[55:48];
assign o1[55:48] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra1==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra1==wa0)) ? i0[55:48] : o01[55:48];
assign o1[63:56] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra1==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra1==wa0)) ? i0[63:56] : o01[63:56];
375,9 → 369,6
assign o2[55:48] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra2==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra2==wa0)) ? i0[55:48] : o02[55:48];
assign o2[55:48] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra2==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra2==wa0)) ? i0[55:48] : o02[55:48];
assign o2[63:56] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra2==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra2==wa0)) ? i0[63:56] : o02[63:56];
403,9 → 394,6
assign o3[55:48] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra3==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra3==wa0)) ? i0[55:48] : o03[55:48];
assign o3[55:48] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra3==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra3==wa0)) ? i0[55:48] : o03[55:48];
assign o3[63:56] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra3==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra3==wa0)) ? i0[63:56] : o03[63:56];
431,9 → 419,6
assign o4[55:48] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra4==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra4==wa0)) ? i0[55:48] : o04[55:48];
assign o4[55:48] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra4==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra4==wa0)) ? i0[55:48] : o04[55:48];
assign o4[63:56] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra4==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra4==wa0)) ? i0[63:56] : o04[63:56];
459,9 → 444,6
assign o5[55:48] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra5==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra5==wa0)) ? i0[55:48] : o05[55:48];
assign o5[55:48] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra5==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra5==wa0)) ? i0[55:48] : o05[55:48];
assign o5[63:56] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra5==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra5==wa0)) ? i0[63:56] : o05[63:56];
/FT64v5/rtl/twoway/FT64_regfile2w9r_oc.v
0,0 → 1,611
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2018 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// This source file is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This source file is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//
// Register file with two write ports and six read ports.
// ============================================================================
//
`include "FT64_config.vh"
 
module FT64_regfileRam_sim(clka, ena, wea, addra, dina, clkb, enb, addrb, doutb);
parameter WID=64;
parameter RBIT = 11;
input clka;
input ena;
input [7:0] wea;
input [RBIT:0] addra;
input [WID-1:0] dina;
input clkb;
input enb;
input [RBIT:0] addrb;
output [WID-1:0] doutb;
 
integer n;
(* RAM_STYLE="BLOCK" *)
reg [64:0] mem [0:4095];
reg [RBIT:0] raddrb;
 
initial begin
for (n = 0; n < 4096; n = n + 1)
mem[n] = 0;
end
 
always @(posedge clka) if (ena & wea[0]) mem[addra][7:0] <= dina[7:0];
always @(posedge clka) if (ena & wea[1]) mem[addra][15:8] <= dina[15:8];
always @(posedge clka) if (ena & wea[2]) mem[addra][23:16] <= dina[23:16];
always @(posedge clka) if (ena & wea[3]) mem[addra][31:24] <= dina[31:24];
always @(posedge clka) if (ena & wea[4]) mem[addra][39:32] <= dina[39:32];
always @(posedge clka) if (ena & wea[5]) mem[addra][47:40] <= dina[47:40];
always @(posedge clka) if (ena & wea[6]) mem[addra][55:48] <= dina[55:48];
always @(posedge clka) if (ena & wea[7]) mem[addra][63:56] <= dina[63:56];
 
always @(posedge clkb)
raddrb <= addrb;
assign doutb = mem[raddrb];
endmodule
 
module FT64_regfile2w9r_oc(clk4x, clk, wr0, wr1, we0, we1, wa0, wa1, i0, i1,
rclk, ra0, ra1, ra2, ra3, ra4, ra5, ra6, ra7, ra8,
o0, o1, o2, o3, o4, o5, o6, o7, o8);
parameter WID=64;
parameter RBIT = 11;
input clk4x;
input clk;
input wr0;
input wr1;
input [7:0] we0;
input [7:0] we1;
input [RBIT:0] wa0;
input [RBIT:0] wa1;
input [WID-1:0] i0;
input [WID-1:0] i1;
input rclk;
input [RBIT:0] ra0;
input [RBIT:0] ra1;
input [RBIT:0] ra2;
input [RBIT:0] ra3;
input [RBIT:0] ra4;
input [RBIT:0] ra5;
input [RBIT:0] ra6;
input [RBIT:0] ra7;
input [RBIT:0] ra8;
output [WID-1:0] o0;
output [WID-1:0] o1;
output [WID-1:0] o2;
output [WID-1:0] o3;
output [WID-1:0] o4;
output [WID-1:0] o5;
output [WID-1:0] o6;
output [WID-1:0] o7;
output [WID-1:0] o8;
 
reg wr;
reg [RBIT:0] wa;
reg [WID-1:0] i;
reg [7:0] we;
wire [WID-1:0] o00, o01, o02, o03, o04, o05, o06, o07, o08;
reg wr1x;
reg [RBIT:0] wa1x;
reg [WID-1:0] i1x;
reg [7:0] we1x;
 
integer n;
 
`ifdef SIM
FT64_regfileRam_sim urf10 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra0),
.doutb(o00)
);
 
FT64_regfileRam_sim urf11 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra1),
.doutb(o01)
);
 
FT64_regfileRam_sim urf12 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra2),
.doutb(o02)
);
 
FT64_regfileRam_sim urf13 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra3),
.doutb(o03)
);
 
FT64_regfileRam_sim urf14 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra4),
.doutb(o04)
);
 
FT64_regfileRam_sim urf15 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra5),
.doutb(o05)
);
 
FT64_regfileRam_sim urf16 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra6),
.doutb(o06)
);
 
FT64_regfileRam_sim urf17 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra7),
.doutb(o07)
);
 
FT64_regfileRam_sim urf18 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.addrb(ra8),
.doutb(o08)
);
`else
FT64_regfileRam urf10 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra0),
.dinb(64'h00),
.doutb(o00)
);
 
FT64_regfileRam urf11 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra1),
.dinb(64'h00),
.doutb(o01)
);
 
FT64_regfileRam urf12 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra2),
.dinb(64'h00),
.doutb(o02)
);
 
FT64_regfileRam urf13 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra3),
.dinb(64'h00),
.doutb(o03)
);
 
FT64_regfileRam urf14 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra4),
.dinb(64'h00),
.doutb(o04)
);
 
FT64_regfileRam urf15 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra5),
.dinb(64'h00),
.doutb(o05)
);
 
FT64_regfileRam urf16 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra6),
.dinb(64'h00),
.doutb(o06)
);
 
FT64_regfileRam urf17 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra7),
.dinb(64'h00),
.doutb(o07)
);
 
FT64_regfileRam urf18 (
.clka(clk4x),
.ena(wr),
.wea(we),
.addra(wa),
.dina(i),
.clkb(rclk),
.enb(1'b1),
.web(8'b0),
.addrb(ra8),
.dinb(64'h00),
.doutb(o08)
);
`endif
 
// The same clock edge that would normally update the register file is the
// clock edge that causes the data to disappear for the next cycle. The
// data needs to be held onto so that it can update the register file on
// the next 4x clock.
always @(posedge clk)
begin
wr1x <= wr1;
we1x <= we1;
wa1x <= wa1;
i1x <= i1;
end
 
reg wclk2;
always @(posedge clk4x)
begin
wclk2 <= clk;
if (clk & ~wclk2) begin
wr <= wr0;
we <= we0;
wa <= wa0;
i <= i0;
end
else if (~clk & wclk2) begin
wr <= wr1x;
we <= we1x;
wa <= wa1x;
i <= i1x;
end
else begin
wr <= 1'b0;
we <= 8'h00;
wa <= 'd0;
i <= 'd0;
end
end
 
assign o0[7:0] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra0==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra0==wa0)) ? i0[7:0] : o00[7:0];
assign o0[15:8] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra0==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra0==wa0)) ? i0[15:8] : o00[15:8];
assign o0[23:16] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra0==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra0==wa0)) ? i0[23:16] : o00[23:16];
assign o0[31:24] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra0==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra0==wa0)) ? i0[31:24] : o00[31:24];
assign o0[39:32] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra0==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra0==wa0)) ? i0[39:32] : o00[39:32];
assign o0[47:40] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra0==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra0==wa0)) ? i0[47:40] : o00[47:40];
assign o0[55:48] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra0==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra0==wa0)) ? i0[55:48] : o00[55:48];
assign o0[63:56] = ra0[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra0==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra0==wa0)) ? i0[63:56] : o00[63:56];
 
assign o1[7:0] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra1==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra1==wa0)) ? i0[7:0] : o01[7:0];
assign o1[15:8] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra1==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra1==wa0)) ? i0[15:8] : o01[15:8];
assign o1[23:16] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra1==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra1==wa0)) ? i0[23:16] : o01[23:16];
assign o1[31:24] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra1==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra1==wa0)) ? i0[31:24] : o01[31:24];
assign o1[39:32] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra1==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra1==wa0)) ? i0[39:32] : o01[39:32];
assign o1[47:40] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra1==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra1==wa0)) ? i0[47:40] : o01[47:40];
assign o1[55:48] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra1==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra1==wa0)) ? i0[55:48] : o01[55:48];
assign o1[63:56] = ra1[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra1==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra1==wa0)) ? i0[63:56] : o01[63:56];
 
assign o2[7:0] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra2==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra2==wa0)) ? i0[7:0] : o02[7:0];
assign o2[15:8] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra2==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra2==wa0)) ? i0[15:8] : o02[15:8];
assign o2[23:16] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra2==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra2==wa0)) ? i0[23:16] : o02[23:16];
assign o2[31:24] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra2==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra2==wa0)) ? i0[31:24] : o02[31:24];
assign o2[39:32] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra2==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra2==wa0)) ? i0[39:32] : o02[39:32];
assign o2[47:40] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra2==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra2==wa0)) ? i0[47:40] : o02[47:40];
assign o2[55:48] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra2==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra2==wa0)) ? i0[55:48] : o02[55:48];
assign o2[63:56] = ra2[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra2==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra2==wa0)) ? i0[63:56] : o02[63:56];
 
assign o3[7:0] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra3==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra3==wa0)) ? i0[7:0] : o03[7:0];
assign o3[15:8] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra3==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra3==wa0)) ? i0[15:8] : o03[15:8];
assign o3[23:16] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra3==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra3==wa0)) ? i0[23:16] : o03[23:16];
assign o3[31:24] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra3==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra3==wa0)) ? i0[31:24] : o03[31:24];
assign o3[39:32] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra3==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra3==wa0)) ? i0[39:32] : o03[39:32];
assign o3[47:40] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra3==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra3==wa0)) ? i0[47:40] : o03[47:40];
assign o3[55:48] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra3==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra3==wa0)) ? i0[55:48] : o03[55:48];
assign o3[63:56] = ra3[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra3==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra3==wa0)) ? i0[63:56] : o03[63:56];
 
assign o4[7:0] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra4==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra4==wa0)) ? i0[7:0] : o04[7:0];
assign o4[15:8] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra4==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra4==wa0)) ? i0[15:8] : o04[15:8];
assign o4[23:16] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra4==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra4==wa0)) ? i0[23:16] : o04[23:16];
assign o4[31:24] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra4==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra4==wa0)) ? i0[31:24] : o04[31:24];
assign o4[39:32] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra4==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra4==wa0)) ? i0[39:32] : o04[39:32];
assign o4[47:40] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra4==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra4==wa0)) ? i0[47:40] : o04[47:40];
assign o4[55:48] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra4==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra4==wa0)) ? i0[55:48] : o04[55:48];
assign o4[63:56] = ra4[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra4==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra4==wa0)) ? i0[63:56] : o04[63:56];
 
assign o5[7:0] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra5==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra5==wa0)) ? i0[7:0] : o05[7:0];
assign o5[15:8] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra5==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra5==wa0)) ? i0[15:8] : o05[15:8];
assign o5[23:16] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra5==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra5==wa0)) ? i0[23:16] : o05[23:16];
assign o5[31:24] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra5==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra5==wa0)) ? i0[31:24] : o05[31:24];
assign o5[39:32] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra5==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra5==wa0)) ? i0[39:32] : o05[39:32];
assign o5[47:40] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra5==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra5==wa0)) ? i0[47:40] : o05[47:40];
assign o5[55:48] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra5==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra5==wa0)) ? i0[55:48] : o05[55:48];
assign o5[63:56] = ra5[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra5==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra5==wa0)) ? i0[63:56] : o05[63:56];
 
assign o6[7:0] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra6==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra6==wa0)) ? i0[7:0] : o06[7:0];
assign o6[15:8] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra6==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra6==wa0)) ? i0[15:8] : o06[15:8];
assign o6[23:16] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra6==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra6==wa0)) ? i0[23:16] : o06[23:16];
assign o6[31:24] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra6==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra6==wa0)) ? i0[31:24] : o06[31:24];
assign o6[39:32] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra6==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra6==wa0)) ? i0[39:32] : o06[39:32];
assign o6[47:40] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra6==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra6==wa0)) ? i0[47:40] : o06[47:40];
assign o6[55:48] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra6==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra6==wa0)) ? i0[55:48] : o06[55:48];
assign o6[63:56] = ra6[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra6==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra6==wa0)) ? i0[63:56] : o06[63:56];
 
assign o7[7:0] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra7==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra7==wa0)) ? i0[7:0] : o07[7:0];
assign o7[15:8] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra7==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra7==wa0)) ? i0[15:8] : o07[15:8];
assign o7[23:16] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra7==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra7==wa0)) ? i0[23:16] : o07[23:16];
assign o7[31:24] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra7==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra7==wa0)) ? i0[31:24] : o07[31:24];
assign o7[39:32] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra7==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra7==wa0)) ? i0[39:32] : o07[39:32];
assign o7[47:40] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra7==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra7==wa0)) ? i0[47:40] : o07[47:40];
assign o7[55:48] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra7==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra7==wa0)) ? i0[55:48] : o07[55:48];
assign o7[63:56] = ra7[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra7==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra7==wa0)) ? i0[63:56] : o07[63:56];
 
assign o8[7:0] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[0] && (ra8==wa1)) ? i1[7:0] :
(wr0 && we0[0] && (ra8==wa0)) ? i0[7:0] : o08[7:0];
assign o8[15:8] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[1] && (ra8==wa1)) ? i1[15:8] :
(wr0 && we0[1] && (ra8==wa0)) ? i0[15:8] : o08[15:8];
assign o8[23:16] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[2] && (ra8==wa1)) ? i1[23:16] :
(wr0 && we0[2] && (ra8==wa0)) ? i0[23:16] : o08[23:16];
assign o8[31:24] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[3] && (ra8==wa1)) ? i1[31:24] :
(wr0 && we0[3] && (ra8==wa0)) ? i0[31:24] : o08[31:24];
assign o8[39:32] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[4] && (ra8==wa1)) ? i1[39:32] :
(wr0 && we0[4] && (ra8==wa0)) ? i0[39:32] : o08[39:32];
assign o8[47:40] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[5] && (ra8==wa1)) ? i1[47:40] :
(wr0 && we0[5] && (ra8==wa0)) ? i0[47:40] : o08[47:40];
assign o8[55:48] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[6] && (ra8==wa1)) ? i1[55:48] :
(wr0 && we0[6] && (ra8==wa0)) ? i0[55:48] : o08[55:48];
assign o8[63:56] = ra8[4:0]==5'd0 ? {8{1'b0}} :
(wr1 && we1[7] && (ra8==wa1)) ? i1[63:56] :
(wr0 && we0[7] && (ra8==wa0)) ? i0[63:56] : o08[63:56];
 
endmodule
 

powered by: WebSVN 2.1.0

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