1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-30 02:32:53 +08:00

Fixing mutual exclusive bug on receiver

-When a read response is detected, there should be no spurious transactions to the RD/WR request fifos.
-Move the "filter" backt to the erx_protocol block
-Removed the remap bypass signal (was hacky)
-Passes simulations again..
This commit is contained in:
Andreas Olofsson 2015-08-14 15:37:37 -04:00
parent 21686d31cc
commit ede8656081
6 changed files with 108 additions and 123 deletions

View File

@ -2,10 +2,9 @@
module erx_arbiter (/*AUTOARG*/
// Outputs
rx_rd_wait, rx_wr_wait, edma_wait, ecfg_wait, rxwr_access,
rxwr_packet, rxrd_access, rxrd_packet,
rxrr_access, rxrr_packet,
rxwr_packet, rxrd_access, rxrd_packet, rxrr_access, rxrr_packet,
// Inputs
erx_access, erx_packet, emmu_access, emmu_packet, edma_access,
erx_rr_access, erx_packet, emmu_access, emmu_packet, edma_access,
edma_packet, ecfg_access, ecfg_packet, timeout, rxwr_wait,
rxrd_wait, rxrr_wait
);
@ -17,13 +16,13 @@ module erx_arbiter (/*AUTOARG*/
parameter RFAW = 6;
//From IO (for rr)
input erx_access;
//From IO (for rr)
input erx_rr_access;
input [PW-1:0] erx_packet;
output rx_rd_wait; //for IO
output rx_wr_wait; //for IO
//From EMMU
//From EMMU (writes)
input emmu_access;
input [PW-1:0] emmu_packet;
@ -57,83 +56,41 @@ module erx_arbiter (/*AUTOARG*/
//wires
wire emmu_write;
wire [1:0] emmu_datamode;
wire [3:0] emmu_ctrlmode;
wire [31:0] emmu_dstaddr;
wire [31:0] emmu_srcaddr;
wire [31:0] emmu_data;
wire emmu_read;
wire erx_write;
wire [1:0] erx_datamode;
wire [3:0] erx_ctrlmode;
wire [31:0] erx_dstaddr;
wire [31:0] erx_srcaddr;
wire [31:0] erx_data;
wire erx_read;
wire erx_rr_access;
wire [11:0] myid;
//####################################
//Splicing pakets
//####################################
assign myid[11:0] = ID;
packet2emesh p2e_erx (// Outputs
.access_out (),
.write_out (erx_write),
.datamode_out (erx_datamode[1:0]),
.ctrlmode_out (erx_ctrlmode[3:0]),
.dstaddr_out (erx_dstaddr[AW-1:0]),
.data_out (erx_data[DW-1:0]),
.srcaddr_out (erx_srcaddr[AW-1:0]),
// Inputs
.packet_in (erx_packet[PW-1:0])
);
packet2emesh p2e_mmu (// Outputs
.access_out (),
.write_out (emmu_write),
.datamode_out (emmu_datamode[1:0]),
.ctrlmode_out (emmu_ctrlmode[3:0]),
.dstaddr_out (emmu_dstaddr[AW-1:0]),
.data_out (emmu_data[DW-1:0]),
.srcaddr_out (emmu_srcaddr[AW-1:0]),
// Inputs
.packet_in (emmu_packet[PW-1:0])
);
//####################################
//Read response path, bypass mmu
//####################################
assign erx_rr_access = (erx_access &
erx_write &
(erx_dstaddr[31:20] == myid[11:0]) &
(erx_dstaddr[19:16] == `EGROUP_RR) // Not sure about this...
);
assign rxrr_access = erx_rr_access |
ecfg_access;
//####################################
//Read response path (from IO or cfg)
//####################################
assign rxrr_access = erx_rr_access |
ecfg_access;
assign rxrr_packet[PW-1:0] = erx_rr_access ? erx_packet[PW-1:0] :
ecfg_packet[PW-1:0];
assign ecfg_wait = erx_rr_access;
assign ecfg_wait = erx_rr_access;
//####################################
//Write Path (direct)
//####################################
assign emmu_write = emmu_packet[1];
assign rxwr_access = emmu_access &
emmu_write;
assign rxwr_access = emmu_access & emmu_write;
assign rxwr_packet[PW-1:0] = emmu_packet[PW-1:0];
//####################################
//Read Path
//Read Request Path
//####################################
assign emmu_read = (emmu_access & ~emmu_write);
assign emmu_read = emmu_access & ~emmu_write;
assign rxrd_access = emmu_read | edma_access;
@ -149,7 +106,8 @@ module erx_arbiter (/*AUTOARG*/
assign edma_wait = rxrd_wait | emmu_read;
assign erx_cfg_wait = rxwr_wait | rxrr_wait;
endmodule // erx_disty
endmodule // erx_arbiter
// Local Variables:
// verilog-library-directories:("." "../../common/hdl" "../../emmu/hdl")
// End:
@ -158,7 +116,7 @@ endmodule // erx_disty
/*
This file is part of the Parallella Project.
Copyright (C) 2014 Adapteva, Inc.
Copyright (C) 2015 Adapteva, Inc.
Contributed by Andreas Olofsson <andreas@adapteva.com>
This program is free software: you can redistribute it and/or modify

View File

@ -61,8 +61,9 @@ module erx_core (/*AUTOARG*/
wire [PW-1:0] emesh_remap_packet; // From erx_remap of erx_remap.v
wire emmu_access; // From erx_mmu of emmu.v
wire [PW-1:0] emmu_packet; // From erx_mmu of emmu.v
wire erx_access; // From erx_protocol of erx_protocol.v
wire [PW-1:0] erx_packet; // From erx_protocol of erx_protocol.v
wire erx_rdwr_access; // From erx_protocol of erx_protocol.v
wire erx_rr_access; // From erx_protocol of erx_protocol.v
wire [14:0] mi_addr; // From erx_cfgif of ecfg_if.v
wire [DW-1:0] mi_cfg_dout; // From erx_cfg of erx_cfg.v
wire mi_cfg_en; // From erx_cfgif of ecfg_if.v
@ -75,7 +76,6 @@ module erx_core (/*AUTOARG*/
wire mi_we; // From erx_cfgif of ecfg_if.v
wire mmu_enable; // From erx_cfg of erx_cfg.v
wire [31:0] remap_base; // From erx_cfg of erx_cfg.v
wire remap_bypass; // From erx_protocol of erx_protocol.v
wire [1:0] remap_mode; // From erx_cfg of erx_cfg.v
wire [11:0] remap_pattern; // From erx_cfg of erx_cfg.v
wire [11:0] remap_sel; // From erx_cfg of erx_cfg.v
@ -102,9 +102,9 @@ module erx_core (/*AUTOARG*/
defparam erx_protocol.ID=ID;
erx_protocol erx_protocol (/*AUTOINST*/
// Outputs
.erx_access (erx_access),
.erx_rdwr_access (erx_rdwr_access),
.erx_rr_access (erx_rr_access),
.erx_packet (erx_packet[PW-1:0]),
.remap_bypass (remap_bypass),
// Inputs
.reset (reset),
.rx_enable (rx_enable),
@ -122,6 +122,7 @@ module erx_core (/*AUTOARG*/
/*erx_remap AUTO_TEMPLATE (
.emesh_\(.*\)_out (emesh_remap_\1[]),
//Inputs
.emesh_access_in (erx_rdwr_access),
.emesh_\(.*\)_in (erx_\1[]),
.mmu_en (ecfg_rx_mmu_enable),
.emesh_packet_hi_out (),
@ -136,13 +137,12 @@ module erx_core (/*AUTOARG*/
// Inputs
.clk (clk),
.reset (reset),
.emesh_access_in(erx_access), // Templated
.emesh_access_in(erx_rdwr_access), // Templated
.emesh_packet_in(erx_packet[PW-1:0]), // Templated
.remap_mode (remap_mode[1:0]),
.remap_sel (remap_sel[11:0]),
.remap_pattern (remap_pattern[11:0]),
.remap_base (remap_base[31:0]),
.remap_bypass (remap_bypass),
.rx_rd_wait (rx_rd_wait),
.rx_wr_wait (rx_wr_wait));
@ -160,15 +160,14 @@ module erx_core (/*AUTOARG*/
.wr_clk (clk),
.mi_dout (mi_mmu_dout[DW-1:0]),
.emesh_packet_hi_out (),
.mmu_bp (remap_bypass),
.mi_en (mi_mmu_en),
.emesh_rd_wait (rx_rd_wait),
.emesh_wr_wait (rx_wr_wait),
);
*/
emmu erx_mmu (
/*AUTOINST*/
emmu erx_mmu (.mmu_bp (1'b0),
/*AUTOINST*/
// Outputs
.mi_dout (mi_mmu_dout[DW-1:0]), // Templated
.emesh_access_out (emmu_access), // Templated
@ -179,7 +178,6 @@ module erx_core (/*AUTOARG*/
.rd_clk (clk), // Templated
.wr_clk (clk), // Templated
.mmu_en (mmu_enable), // Templated
.mmu_bp (remap_bypass), // Templated
.mi_en (mi_mmu_en), // Templated
.mi_we (mi_we),
.mi_addr (mi_addr[14:0]),
@ -364,7 +362,7 @@ module erx_core (/*AUTOARG*/
.rxrr_access (rxrr_access),
.rxrr_packet (rxrr_packet[PW-1:0]),
// Inputs
.erx_access (erx_access),
.erx_rr_access (erx_rr_access),
.erx_packet (erx_packet[PW-1:0]),
.emmu_access (emmu_access),
.emmu_packet (emmu_packet[PW-1:0]),

View File

@ -1,3 +1,6 @@
/*
This block receives the IO transaction and converts to a 104 bit packet.
*/
`include "elink_constants.v"
module erx_io (/*AUTOARG*/
// Outputs

View File

@ -1,16 +1,11 @@
/*
########################################################################
EPIPHANY eLink RX Protocol block
########################################################################
This block takes the parallel output of the input deserializers, locates
valid frame transitions, and decodes the bytes into standard eMesh
protocol (104-bit transactions).
This block handles the autoincrement needed for bursting and detects
read responses
*/
`include "elink_regmap.v"
module erx_protocol (/*AUTOARG*/
// Outputs
erx_access, erx_packet, remap_bypass,
erx_rdwr_access, erx_rr_access, erx_packet,
// Inputs
reset, rx_enable, clk, rx_packet, rx_burst, rx_access
);
@ -18,7 +13,7 @@ module erx_protocol (/*AUTOARG*/
parameter AW = 32;
parameter DW = 32;
parameter PW = 104;
parameter ID = 0;
parameter ID = 12'h800; //link id
// System reset input
@ -32,15 +27,25 @@ module erx_protocol (/*AUTOARG*/
input rx_access;
// Output to MMU / filter
output erx_access;
output erx_rdwr_access;
output erx_rr_access;
output [PW-1:0] erx_packet;
output remap_bypass; //needed for remapping logic
//wires
reg [31:0] dstaddr_reg;
wire [31:0] dstaddr_next;
wire [31:0] dstaddr_mux;
reg erx_access;
reg erx_rdwr_access;
reg erx_rr_access;
reg [PW-1:0] erx_packet;
wire [11:0] myid;
wire [31:0] rx_addr;
wire read_response;
//parsing inputs
assign myid[11:0] = ID;
assign rx_addr[31:0] = rx_packet[39:8];
//Address generator for bursting
always @ (posedge clk)
@ -50,15 +55,25 @@ module erx_protocol (/*AUTOARG*/
assign dstaddr_next[31:0] = dstaddr_reg[31:0] + 4'b1000;
assign dstaddr_mux[31:0] = rx_burst ? dstaddr_next[31:0] :
rx_packet[39:8];
rx_addr[31:0];
//Pipeline stage
//Read response detector
assign read_response = (rx_addr[31:20] == myid[11:0]) &
(rx_addr[19:16] == `EGROUP_RR);
//Pipeline stage and decode
always @ (posedge clk)
begin
erx_access <= rx_access;
//Write/read request
erx_rdwr_access <= rx_access & ~read_response;
//Read response
erx_rr_access <= rx_access & read_response;
//Common packet
erx_packet[PW-1:0] <= {rx_packet[PW-1:40],
dstaddr_mux[31:0],
rx_packet[7:0]
dstaddr_mux[31:0],
rx_packet[7:0]
};
end

View File

@ -3,8 +3,7 @@ module erx_remap (/*AUTOARG*/
emesh_access_out, emesh_packet_out,
// Inputs
clk, reset, emesh_access_in, emesh_packet_in, remap_mode,
remap_sel, remap_pattern, remap_base, remap_bypass, rx_rd_wait,
rx_wr_wait
remap_sel, remap_pattern, remap_base, rx_rd_wait, rx_wr_wait
);
parameter AW = 32;
@ -25,7 +24,6 @@ module erx_remap (/*AUTOARG*/
input [11:0] remap_sel; //number of bits to remap
input [11:0] remap_pattern; //static pattern to map to
input [31:0] remap_base; //remap offset
input remap_bypass; //dynamic bypass (read request | link match)
//Output to TX IO
output emesh_access_out;
@ -39,17 +37,21 @@ module erx_remap (/*AUTOARG*/
wire [31:0] dynamic_remap;
wire [31:0] remap_mux;
wire write_in;
wire read_in;
wire [31:0] addr_in;
wire [31:0] addr_out;
wire remap_en;
reg emesh_access_out;
reg [PW-1:0] emesh_packet_out;
//TODO:FIX!
//TODO:FIX!??
parameter[5:0] colid = ID[5:0];
//parsing packet
assign addr_in[31:0] = emesh_packet_in[39:8];
assign write_in = emesh_packet_in[1];
assign read_in = ~emesh_packet_in[1];
//simple static remap
assign static_remap[31:20] = (remap_sel[11:0] & remap_pattern[11:0]) |
@ -58,31 +60,32 @@ module erx_remap (/*AUTOARG*/
assign static_remap[19:0] = addr_in[19:0];
//more complex compresssed map
assign dynamic_remap[31:0] = addr_in[31:0] //input
- (colid << 20) //subtracing elink (start at 0)
assign dynamic_remap[31:0] = addr_in[31:0] //input
- (colid << 20) //subtracing elink (start at 0)
+ remap_base[31:0] //adding back base
- (addr_in[31:26]<<$clog2(colid));
wire remap_en = ~(remap_mode[1:0]==2'b00);
assign remap_mux[31:0] = (remap_bypass | ~remap_en) ? addr_in[31:0] :
(remap_mode[1:0]==2'b01) ? static_remap[31:0] :
dynamic_remap[31:0];
//Static, dynamic, or no remap
assign remap_mux[31:0] = (remap_mode[1:0]==2'b00) ? addr_in[31:0] :
(remap_mode[1:0]==2'b01) ? static_remap[31:0] :
dynamic_remap[31:0];
//Access
always @ (posedge clk)
if (reset)
begin
emesh_access_out <= 'b0;
end
else if((write_in & ~rx_wr_wait) | (~write_in & ~rx_rd_wait))
begin
emesh_access_out <= emesh_access_in;
emesh_packet_out[PW-1:0] <= {emesh_packet_in[103:40],
remap_mux[31:0],
emesh_packet_in[7:0]
};
end
emesh_access_out <= 1'b0;
else if((write_in & ~rx_wr_wait) | (read_in & ~rx_rd_wait))
emesh_access_out <= emesh_access_in;
//Packet
always @ (posedge clk)
if((write_in & ~rx_wr_wait) | (read_in & ~rx_rd_wait))
emesh_packet_out[PW-1:0] <= {emesh_packet_in[103:40],
remap_mux[31:0],
emesh_packet_in[7:0]
};
endmodule // etx_mux

View File

@ -149,13 +149,23 @@ module etx_arbiter (/*AUTOARG*/
//Pipeline + stall
assign write_in = etx_mux[1];
//access
always @ (posedge clk)
if (reset)
begin
etx_access <= 1'b0;
etx_rr <= 1'b0;
end
else if (access_in & (write_in & ~etx_wr_wait) | (~write_in & ~etx_rd_wait))
begin
etx_access <= access_in;
etx_rr <= txrr_grant;
end
//packet
always @ (posedge clk)
if (access_in & (write_in & ~etx_wr_wait) | (~write_in & ~etx_rd_wait))
begin
etx_access <= access_in;
etx_packet[PW-1:0] <= etx_mux[PW-1:0];
etx_rr <= txrr_grant;
end
etx_packet[PW-1:0] <= etx_mux[PW-1:0];
endmodule // etx_arbiter
// Local Variables:
@ -164,8 +174,6 @@ endmodule // etx_arbiter
/*
File: etx_arbiter.v
Copyright (C) 2015 Adapteva, Inc.
Contributed by Andreas Olofsson <andreas@adapteva.com>