URL
https://opencores.org/ocsvn/thor/thor/trunk
Subversion Repositories thor
Compare Revisions
- This comparison shows the changes necessary to convert path
/thor/trunk/FT64v5/rtl
- from Rev 56 to Rev 57
- ↔ Reverse comparison
Rev 56 → Rev 57
/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; |
/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) |
); |
/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) |
/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; |
/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":".", |
/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 |
/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) |
/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; |
/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 |
|
/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 |
|
/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]; |
/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 |
|