URL
https://opencores.org/ocsvn/cryptosorter/cryptosorter/trunk
Subversion Repositories cryptosorter
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 4 to Rev 5
- ↔ Reverse comparison
Rev 4 → Rev 5
/trunk/lib/bsv/SizedFIFO_fpga/mkSizedFIFO_fpga.bsv
0,0 → 1,91
package mkSizedFIFO_fpga; |
|
import FIFO::*; |
import RWire::*; |
import RegFile::*; |
import IFPGA_FIFO::*; |
|
module mkSizedFIFO_fpga (IFPGA_FIFO#(f_type, size)) |
provisos( |
Bits#(f_type, f_type_length), |
Add#(TLog#(size), 0, lg_size), |
Add#(TLog#(size), 1, lg_size_plus), |
Add#(2, TLog#(size),lg_size_plus_plus), |
Add#(1, lg_size_plus, lg_size_plus_plus) |
); |
|
RegFile#(Bit#(TLog#(size)), f_type) data <- mkRegFile(0, fromInteger(valueof(TSub#(size,1)))); |
Reg#(Bit#(lg_size_plus)) number_enqueued <- mkReg(0); |
Reg#(Bit#(TLog#(size))) base_ptr <- mkReg(0); |
RWire#(Bit#(0)) deque_pending <- mkRWire(); |
RWire#(Bit#(0)) clear_pending <- mkRWire(); |
RWire#(f_type) enque_pending <- mkRWire(); |
|
// We'll have problems with non-saturating additions, so we ought to add some checks |
// Strongly Recommend power of 2 sizes to simpilfy logic. |
|
rule update; |
if(clear_pending.wget() matches tagged Valid .v) |
begin |
//clear is occuring, we drop a pending enqueue on the floor. |
number_enqueued <= 0; |
base_ptr <= 0; |
end |
else |
begin |
if(enque_pending.wget() matches tagged Valid .new_data) |
begin |
if(deque_pending.wget() matches tagged Valid .dp) |
begin |
// enque and deque occuring.. no change to net. |
base_ptr <= (zeroExtend(base_ptr) == fromInteger(valueof(size)-1))? 0:base_ptr + 1; |
Bit#(lg_size_plus_plus) offset = zeroExtend((zeroExtend(base_ptr) + number_enqueued)); |
data.upd((offset >= fromInteger(valueof(size)))? |
truncate(offset - truncate(fromInteger(valueof(size)))): |
truncate(offset), |
new_data); |
end |
else |
begin |
number_enqueued <= number_enqueued + 1; |
Bit#(lg_size_plus_plus) offset = zeroExtend((zeroExtend(base_ptr) + number_enqueued)); |
data.upd((offset >= fromInteger(valueof(size)))? |
truncate(offset - truncate(fromInteger(valueof(size)))): |
truncate(offset), |
new_data); |
end |
end |
else |
begin |
if(deque_pending.wget() matches tagged Valid .dp) |
begin |
//enque and deque occuring.. no change to net. |
base_ptr <= (zeroExtend(base_ptr) == truncate(fromInteger(valueof(size)-1)))? 0:base_ptr + 1; |
number_enqueued <= number_enqueued - 1; |
end |
end |
end |
endrule |
|
interface FIFO fifo; |
|
method Action enq (f_type value) if(number_enqueued < fromInteger(valueof(size))); |
enque_pending.wset(value); |
endmethod |
|
method Action deq() if(number_enqueued > 0); |
deque_pending.wset(0); |
endmethod |
|
method f_type first() if(number_enqueued > 0); |
return data.sub(base_ptr); |
endmethod |
|
method Action clear(); |
clear_pending.wset(0); |
endmethod |
|
endinterface |
|
endmodule |
endpackage |
/trunk/lib/bsv/SizedFIFO_fpga/IFPGA_FIFO.bsv
0,0 → 1,10
package IFPGA_FIFO; |
|
import FIFO::*; |
|
interface IFPGA_FIFO#(type f_type, numeric type size); |
// Interface for memory, input generator |
interface FIFO#(f_type) fifo; |
endinterface |
|
endpackage |
/trunk/lib/bsv/BRAM/blue_sim_model/BRAM.bsv
0,0 → 1,120
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// Permission is hereby granted, free of charge, to any person |
// obtaining a copy of this software and associated documentation |
// files (the "Software"), to deal in the Software without |
// restriction, including without limitation the rights to use, |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
// copies of the Software, and to permit persons to whom the |
// Software is furnished to do so, subject to the following conditions: |
// |
// The above copyright notice and this permission notice shall be |
// included in all copies or substantial portions of the Software. |
// |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
// OTHER DEALINGS IN THE SOFTWARE. |
//----------------------------------------------------------------------// |
import FIFO::*; |
import RegFile::*; |
|
interface BRAM#(type idx_type, type data_type); |
|
method Action read_req(idx_type idx); |
|
method ActionValue#(data_type) read_resp(); |
|
method Action write(idx_type idx, data_type data); |
|
endinterface |
|
|
module mkBRAM#(Integer low, Integer high) |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type), |
Bounded#(idx_type)); |
|
BRAM#(idx_type, data_type) m <- (valueof(data) == 0) ? |
mkBRAM_Zero() : |
mkBRAM_NonZero(low, high); |
|
return m; |
endmodule |
|
module mkBRAM_NonZero#(Integer low, Integer high) |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type), |
Bounded#(idx_type)); |
RegFile#(idx_type, data_type) arr <- mkRegFileFull(); |
FIFO#(data_type) outfifo <- mkSizedFIFO(8); |
|
method Action read_req(idx_type idx); |
outfifo.enq(arr.sub(idx)); |
endmethod |
|
method ActionValue#(data_type) read_resp(); |
outfifo.deq(); |
return outfifo.first(); |
endmethod |
|
method Action write(idx_type idx, data_type data); |
arr.upd(idx, data); |
endmethod |
endmodule |
|
module mkBRAM_Zero |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
FIFO#(data_type) q <- mkSizedFIFO(8); |
|
method Action read_req(idx_type i); |
q.enq(?); |
endmethod |
|
method Action write(idx_type i, data_type d); |
noAction; |
endmethod |
|
method ActionValue#(data_type) read_resp(); |
q.deq(); |
return q.first(); |
endmethod |
|
endmodule |
|
module mkBRAM_Full |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type), |
Bounded#(idx_type)); |
|
|
BRAM#(idx_type, data_type) br <- mkBRAM(0, valueof(TExp#(idx)) - 1); |
|
return br; |
|
endmodule |
/trunk/lib/bsv/BRAM/BRAM.v
0,0 → 1,110
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// Permission is hereby granted, free of charge, to any person |
// obtaining a copy of this software and associated documentation |
// files (the "Software"), to deal in the Software without |
// restriction, including without limitation the rights to use, |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
// copies of the Software, and to permit persons to whom the |
// Software is furnished to do so, subject to the following conditions: |
// |
// The above copyright notice and this permission notice shall be |
// included in all copies or substantial portions of the Software. |
// |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
// OTHER DEALINGS IN THE SOFTWARE. |
//----------------------------------------------------------------------// |
|
|
module BRAM(CLK, RST_N, |
RD_ADDR, RD_RDY, RD_EN, |
DOUT, DOUT_RDY, DOUT_EN, |
WR_ADDR, WR_VAL, WR_EN); |
|
// synopsys template |
parameter addr_width = 1; |
parameter data_width = 1; |
parameter lo = 0; |
parameter hi = 1; |
|
input CLK; |
input RST_N; |
|
// Read Port |
// req |
input [addr_width - 1 : 0] RD_ADDR; |
input RD_EN; |
output RD_RDY; |
// resp |
output [data_width - 1 : 0] DOUT; |
output DOUT_RDY; |
input DOUT_EN; |
|
// Write Port |
// req |
input [addr_width - 1 : 0] WR_ADDR; |
input [data_width - 1 : 0] WR_VAL; |
input WR_EN; |
|
reg [data_width - 1 : 0] arr[lo:hi]; /*synthesis syn_ramstyle = "block_ram"*/ |
|
reg RD_REQ_MADE; |
reg [data_width - 1 : 0] RAM_OUT; |
|
reg [1:0] CTR; |
|
FIFOL2#(.width(data_width)) q(.RST_N(RST_N), |
.CLK(CLK), |
.D_IN(RAM_OUT), |
.ENQ(RD_REQ_MADE), |
.DEQ(DOUT_EN), |
.CLR(1'b0), |
.D_OUT(DOUT), |
.FULL_N(), |
.EMPTY_N(DOUT_RDY)); |
|
assign RD_RDY = (CTR > 0) || DOUT_EN; |
|
integer x; |
|
always@(posedge CLK) |
begin |
|
|
if (!RST_N) |
begin //Make simulation behavior consistent with Xilinx synthesis |
// synopsys translate_off |
for (x = lo; x < hi; x = x + 1) |
begin |
arr[x] <= 0; |
end |
// synopsys translate_on |
CTR <= 2; |
end |
else |
begin |
|
RD_REQ_MADE <= RD_EN; |
|
if (WR_EN) |
arr[WR_ADDR] <= WR_VAL; |
|
CTR <= (RD_EN) ? |
(DOUT_EN) ? CTR : CTR - 1 : |
(DOUT_EN) ? CTR + 1 : CTR; |
|
RAM_OUT <= arr[RD_ADDR]; |
|
end |
end // always@ (posedge CLK) |
|
endmodule |
/trunk/lib/bsv/BRAM/BRAM.bsv
0,0 → 1,238
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// Permission is hereby granted, free of charge, to any person |
// obtaining a copy of this software and associated documentation |
// files (the "Software"), to deal in the Software without |
// restriction, including without limitation the rights to use, |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
// copies of the Software, and to permit persons to whom the |
// Software is furnished to do so, subject to the following conditions: |
// |
// The above copyright notice and this permission notice shall be |
// included in all copies or substantial portions of the Software. |
// |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
// OTHER DEALINGS IN THE SOFTWARE. |
//----------------------------------------------------------------------// |
import FIFO::*; |
|
//One RAM. |
interface BRAM#(type idx_type, type data_type); |
|
method Action read_req(idx_type idx); |
|
method ActionValue#(data_type) read_resp(); |
|
method Action write(idx_type idx, data_type data); |
|
endinterface |
|
|
//Two RAMs. |
interface BRAM_2#(type idx_type, type data_type); |
|
method Action read_req1(idx_type idx); |
method Action read_req2(idx_type idx); |
|
method ActionValue#(data_type) read_resp1(); |
method ActionValue#(data_type) read_resp2(); |
|
method Action write(idx_type idx, data_type data); |
|
endinterface |
|
//Three RAMs. |
interface BRAM_3#(type idx_type, type data_type); |
|
method Action read_req1(idx_type idx); |
method Action read_req2(idx_type idx); |
method Action read_req3(idx_type idx); |
|
method ActionValue#(data_type) read_resp1(); |
method ActionValue#(data_type) read_resp2(); |
method ActionValue#(data_type) read_resp3(); |
|
method Action write(idx_type idx, data_type data); |
|
endinterface |
|
|
module mkBRAM#(Integer low, Integer high) |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
BRAM#(idx_type, data_type) m <- (valueof(data) == 0) ? |
mkBRAM_Zero() : |
mkBRAM_NonZero(low, high); |
|
return m; |
endmodule |
|
import "BVI" BRAM = module mkBRAM_NonZero#(Integer low, Integer high) |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
default_clock clk(CLK); |
|
parameter addr_width = valueof(idx); |
parameter data_width = valueof(data); |
parameter lo = low; |
parameter hi = high; |
|
method DOUT read_resp() ready(DOUT_RDY) enable(DOUT_EN); |
|
method read_req(RD_ADDR) ready(RD_RDY) enable(RD_EN); |
method write(WR_ADDR, WR_VAL) enable(WR_EN); |
|
schedule read_req CF (read_resp, write); |
schedule read_resp CF (read_req, write); |
schedule write CF (read_req, read_resp); |
|
schedule read_req C read_req; |
schedule read_resp C read_resp; |
schedule write C write; |
|
endmodule |
|
module mkBRAM_Zero |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
FIFO#(data_type) q <- mkLFIFO(); |
|
method Action read_req(idx_type i); |
q.enq(?); |
endmethod |
|
method Action write(idx_type i, data_type d); |
noAction; |
endmethod |
|
method ActionValue#(data_type) read_resp(); |
q.deq(); |
return q.first(); |
endmethod |
|
endmodule |
|
module mkBRAM_Full |
//interface: |
(BRAM#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
|
BRAM#(idx_type, data_type) br <- mkBRAM(0, valueof(TExp#(idx)) - 1); |
|
return br; |
|
endmodule |
module mkBRAM_2#(Integer low, Integer high) |
//interface: |
(BRAM_2#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
BRAM#(idx_type, data_type) br1 <- mkBRAM(low, high); |
BRAM#(idx_type, data_type) br2 <- mkBRAM(low, high); |
|
method read_req1(idx) = br1.read_req(idx); |
method read_req2(idx) = br2.read_req(idx); |
|
method read_resp1() = br1.read_resp(); |
method read_resp2() = br2.read_resp(); |
|
method Action write(idx_type idx, data_type data); |
|
br1.write(idx, data); |
br2.write(idx, data); |
|
endmethod |
|
endmodule |
|
module mkBRAM_2_Full |
//interface: |
(BRAM_2#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
|
BRAM_2#(idx_type, data_type) br <- mkBRAM_2(0, valueof(TExp#(idx)) - 1); |
|
return br; |
|
endmodule |
|
module mkBRAM_3#(Integer low, Integer high) |
//interface: |
(BRAM_3#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
BRAM#(idx_type, data_type) br1 <- mkBRAM(low, high); |
BRAM#(idx_type, data_type) br2 <- mkBRAM(low, high); |
BRAM#(idx_type, data_type) br3 <- mkBRAM(low, high); |
|
method read_req1(idx) = br1.read_req(idx); |
method read_req2(idx) = br2.read_req(idx); |
method read_req3(idx) = br3.read_req(idx); |
|
method read_resp1() = br1.read_resp(); |
method read_resp2() = br2.read_resp(); |
method read_resp3() = br3.read_resp(); |
|
method Action write(idx_type idx, data_type data); |
|
br1.write(idx, data); |
br2.write(idx, data); |
br3.write(idx, data); |
|
endmethod |
|
endmodule |
|
|
module mkBRAM_3_Full |
//interface: |
(BRAM_3#(idx_type, data_type)) |
provisos |
(Bits#(idx_type, idx), |
Bits#(data_type, data), |
Literal#(idx_type)); |
|
|
BRAM_3#(idx_type, data_type) br <- mkBRAM_3(0, valueof(TExp#(idx)) - 1); |
|
return br; |
|
endmodule |
/trunk/lib/bsv/BRAM/readme.txt
0,0 → 1,8
BRAM.bsv and BRAM.v are a bluespec wrapper for a synthesizable fpga BRAM. blue_sim_model directory contains a wholly bluespec cycle accurate model of the BRAM which can be used for simulation/debugging. |
|
These files were created by |
Kermin Fleming (MIT) |
Micheal Pellauer (MIT) |
Eric Chung (CMU) |
|
Caveat Codor. |
/trunk/lib/bsv/BRAMFIFO/BRAMFIFOF.v
0,0 → 1,191
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// Permission is hereby granted, free of charge, to any person |
// obtaining a copy of this software and associated documentation |
// files (the "Software"), to deal in the Software without |
// restriction, including without limitation the rights to use, |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
// copies of the Software, and to permit persons to whom the |
// Software is furnished to do so, subject to the following conditions: |
// |
// The above copyright notice and this permission notice shall be |
// included in all copies or substantial portions of the Software. |
// |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
// OTHER DEALINGS IN THE SOFTWARE. |
//----------------------------------------------------------------------// |
|
|
/*** |
* |
* This module implements a parametric verilog sized fifo. This particular |
* sized fifo will synthesize on to Xilinx block rams. The fifo is parametric |
* in terms of both data width and the number of data stored in the fifo. |
* the interface is gaurded. The fifo is not loopy. |
* The methods supported by the FIFO are clear, dequeue, enqueue, notFull, |
* and notEmpty |
* |
***/ |
|
|
module BRAMFIFOF(CLK, RST_N, |
D_IN, CLR, DEQ, |
ENQ, D_OUT, FULL_N, EMPTY_N); |
|
// synopsys template |
parameter log_data_count = 0; |
parameter data_count = 1; |
parameter data_width = 1; |
|
input CLK; |
input RST_N; |
|
input [data_width - 1 : 0] D_IN; |
input CLR; |
input DEQ; |
input ENQ; |
|
output [data_width - 1 : 0] D_OUT; |
output FULL_N; |
output EMPTY_N; |
|
|
|
reg [data_width - 1 : 0] arr[0:data_count]; /*synthesis syn_ramstyle = "block_ram"*/ |
|
reg skid_flag; |
reg [log_data_count + 2 : 0] fifo_data_count; |
reg [log_data_count + 2 : 0] read_ptr; |
reg [log_data_count + 2 : 0] read_ptr_current; |
reg [log_data_count + 2 : 0] write_ptr; |
reg [data_width - 1 : 0] skid_buffer; // this is a fast output buffer |
reg [data_width - 1 : 0] RAM_OUT; |
|
|
assign D_OUT = (skid_flag)?skid_buffer:RAM_OUT; |
|
assign FULL_N = !(fifo_data_count == data_count); |
assign EMPTY_N = !(fifo_data_count == 0); |
|
integer x; |
|
always@(*) |
begin |
if(DEQ) |
begin |
read_ptr_current = (read_ptr == data_count)?0:(read_ptr + 1); |
end |
else |
begin |
read_ptr_current = read_ptr; |
end |
end |
|
|
|
always@(posedge CLK) |
begin |
if (!RST_N) |
begin //Make simulation behavior consistent with Xilinx synthesis |
// synopsys translate_off |
for (x = 0; x < data_count + 1; x = x + 1) |
begin |
arr[x] <= 0; |
end |
// synopsys translate_on |
fifo_data_count <= 0; |
skid_buffer <= 0; |
skid_flag <= 0; |
read_ptr <= 0; |
write_ptr <= 0; |
//$display("Params: data_count: %d, log_data_count: %d, data_width: %d", data_count, log_data_count, data_width); |
end |
else |
begin |
// assign output buffer |
skid_buffer <= D_IN; |
|
if(CLR) |
begin |
skid_flag <= 0; |
end |
else if(ENQ && ((fifo_data_count == 0) || ((fifo_data_count == 1) && DEQ))) |
begin |
//$display("Enque to output buffer"); |
skid_flag <= 1; |
end |
else |
begin |
skid_flag <= 0; |
end |
|
// write_ptr |
if(CLR) |
begin |
write_ptr <= 0; |
end |
else if(ENQ) |
begin |
//$display("Enque to BRAM[%d]: %d", write_ptr,D_IN); |
write_ptr <= (write_ptr == data_count)?0:(write_ptr + 1); |
end |
else |
begin |
write_ptr <= write_ptr; |
end |
|
//read_ptr |
if(CLR) |
begin |
read_ptr <= 0; |
end |
else if(DEQ) |
begin |
//$display("Advancing read ptr"); |
read_ptr <= (read_ptr == data_count)?0:(read_ptr + 1); |
end |
else |
begin |
read_ptr <= read_ptr; |
end |
|
// assign fifo data_count |
if(CLR) |
begin |
fifo_data_count <= 0; |
end |
else if(ENQ && DEQ) |
begin |
fifo_data_count <= fifo_data_count; |
end |
else if(ENQ) |
begin |
fifo_data_count <= fifo_data_count + 1; |
end |
else if(DEQ) |
begin |
fifo_data_count <= fifo_data_count - 1; |
end |
else |
begin |
fifo_data_count <= fifo_data_count; |
end |
if(ENQ) |
begin |
arr[write_ptr] <= D_IN; |
end |
RAM_OUT <= arr[read_ptr_current]; |
|
end |
end // always@ (posedge CLK) |
|
endmodule |
/trunk/lib/bsv/BRAMFIFO/build/top.v
0,0 → 1,23
module top; |
reg clk; |
reg rst_n; |
|
mkTestBench m(.CLK(clk),.RST_N(rst_n)); |
|
always@(clk) |
#5 clk <= ~clk; |
|
initial |
begin |
$dumpfile("dump.vcd"); |
$dumpvars(4,m); |
rst_n <= 0; |
clk <= 0; |
#50; |
rst_n <= 1; |
|
end |
|
|
|
endmodule |
/trunk/lib/bsv/BRAMFIFO/build/Makefile
0,0 → 1,123
#//----------------------------------------------------------------------// |
#// The MIT License |
#// |
#// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
#// |
#// Permission is hereby granted, free of charge, to any person |
#// obtaining a copy of this software and associated documentation |
#// files (the "Software"), to deal in the Software without |
#// restriction, including without limitation the rights to use, |
#// copy, modify, merge, publish, distribute, sublicense, and/or sell |
#// copies of the Software, and to permit persons to whom the |
#// Software is furnished to do so, subject to the following conditions: |
#// |
#// The above copyright notice and this permission notice shall be |
#// included in all copies or substantial portions of the Software. |
#// |
#// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
#// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
#// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
#// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
#// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
#// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
#// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
#// OTHER DEALINGS IN THE SOFTWARE. |
#//----------------------------------------------------------------------// |
|
|
default : all |
|
basedir = ../ |
bsvlibdir = ../../../bsclib |
verilogdir = ./ |
|
|
#-------------------------------------------------------------------- |
# Sources |
#-------------------------------------------------------------------- |
|
# Library components |
|
bsvclibdir = $(MIT6375_HOME)/install/bsvclib |
bsvclibsrcs = \ |
|
# Bluespec sources |
|
toplevel_module = mkTestBench |
|
srcdir = $(basedir) |
|
|
fpgasrcs = \ |
$(srcdir)/BRAMFIFO.bsv \ |
$(srcdir)/mkTestBench.bsv \ |
$(srcdir)/top.v \ |
$(srcdir)/BRAMFIFOF.v |
|
|
|
#-------------------------------------------------------------------- |
# Build rules |
#-------------------------------------------------------------------- |
|
BSC_COMP = bsc |
#BSC_OPTS = -u -show-module-use - -keep-fires -aggressive-conditions \ |
# -relax-method-earliness -relax-method-urgency -v |
|
BSC_OPTS_SIM = +RTS -K400000k --RTS -u -v -sim -aggressive-conditions |
|
|
BSC_OPTS_VERILOG = +RTS -K400000k --RTS -u -v -verilog -aggressive-conditions -dschedule |
|
BSIM_OPTS = +RTS -K400000k --RTS -sim |
|
# Copy over te bluespec source |
|
$(notdir $(fpgasrcs)) : % : $(srcdir)/% |
cp $< . |
|
$(notdir $(bsvclibsrcs)) : % : $(bsvclibdir)/% |
cp $< . |
|
# Run the bluespec compiler |
|
bsv_TH_vsrc = $(toplevel_module).v |
$(bsv_TH_vsrc) $(bsv_lib_use) : $(notdir $(fpgasrcs) $(bsvclibsrcs)) |
$(BSC_COMP) $(BSC_OPTS_SIM) -g $(toplevel_module) $(toplevel_module).bsv > out.log |
|
bsv : $(toplevel_module).v |
|
|
blue_sim: $(bsv_TH_vsrc) |
$(BSC_COMP) $(BSIM_OPTS) -e $(toplevel_module) *.ba > out.txt |
|
verilog: $(notdir $(fpgasrcs) $(bsvclibsrcs)) |
$(BSC_COMP) $(BSC_OPTS_VERILOG) -g $(toplevel_module) $(toplevel_module).bsv > out.log |
|
verilog_exec: verilog |
iverilog -y$(bsvlibdir) -y$(verilogdir) *.v |
|
|
# Create a schedule file |
|
schedule_rpt = schedule.rpt |
$(schedule_rpt) : $(notdir $(fpgasrcs) $(bsvclibsrcs)) |
rm -rf *.v |
$(BSC_COMP) $(BSC_OPTS_SIM) -show-schedule -show-rule-rel \* \* -g $(toplevel_module) \ |
$(toplevel_module).bsv >& $(schedule_rpt) |
|
junk += $(notdir $(fpgasrcs) ) $(notdir $(bsvclibsrcs)) \ |
$(schedule_rpt) *.use *.bi *.bo *.v bsc.log |
|
#-------------------------------------------------------------------- |
# Default make target |
#-------------------------------------------------------------------- |
|
all : verilog_exec |
|
#-------------------------------------------------------------------- |
# Clean up |
#-------------------------------------------------------------------- |
|
clean : |
rm -rf $(junk) *~ \#* *.cxx *.o *.h *.ba |
/trunk/lib/bsv/BRAMFIFO/mkTestBench.bsv
0,0 → 1,98
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// Permission is hereby granted, free of charge, to any person |
// obtaining a copy of this software and associated documentation |
// files (the "Software"), to deal in the Software without |
// restriction, including without limitation the rights to use, |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
// copies of the Software, and to permit persons to whom the |
// Software is furnished to do so, subject to the following conditions: |
// |
// The above copyright notice and this permission notice shall be |
// included in all copies or substantial portions of the Software. |
// |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
// OTHER DEALINGS IN THE SOFTWARE. |
//----------------------------------------------------------------------// |
|
import BRAMFIFO::*; |
import FIFOF::*; |
import FIFO::*; |
|
/*** |
* |
* This module is a test harness for the BRAMFIFO verilog module. |
* The module compares the behavior of a BRAM based sized FIFO and a |
* standard sized fifo. If their behavior differs at any point during the |
* long pseudo-random test bench, then a failure message is displayed. |
* |
***/ |
|
|
(* synthesize *) |
module mkTest (FIFOF#(Bit#(32))); |
FIFOF#(Bit#(32)) gold <- mkBRAMFIFOF(250); |
FIFO#(Bit#(32)) p <- mkSizedFIFO(6); |
return gold; |
endmodule |
|
|
module mkTestBench (); |
Reg#(Bit#(32)) test_counter <- mkReg(0); |
|
rule test_counter_rl; |
test_counter <= test_counter + 1; |
if(test_counter > 1000000) |
begin |
$display("PASS"); |
$finish; |
end |
endrule |
|
for(Integer i = 2; i < 4; i = i + 1) |
begin |
FIFO#(Bit#(32)) gold <- mkSizedFIFO(i); |
FIFO#(Bit#(32)) test <- mkBRAMFIFO(i); |
Reg#(Bit#(32)) counter <- mkReg(0); |
|
rule count; |
counter <= counter + 1; |
endrule |
|
rule enq_a(counter % fromInteger(i) == 0); |
gold.enq(counter); |
endrule |
|
rule enq_b(counter % fromInteger(i) == 0); |
test.enq(counter); |
endrule |
|
for(Integer j = 2; j < 4; j = j+1) |
begin |
rule deq_check(zeroExtend(counter)%fromInteger(j) == 0); |
if(gold.first() != test.first()) |
begin |
$display("FAIL Not equal! g: %d t: %d i: %d j: %d", gold.first, test.first, i, j); |
end |
else |
begin |
$display("Match: %d i:%d j:%d", gold.first, i,j); |
end |
|
gold.deq; |
test.deq; |
|
endrule |
end |
end |
|
endmodule |
/trunk/lib/bsv/BRAMFIFO/top.v
0,0 → 1,49
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// Permission is hereby granted, free of charge, to any person |
// obtaining a copy of this software and associated documentation |
// files (the "Software"), to deal in the Software without |
// restriction, including without limitation the rights to use, |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
// copies of the Software, and to permit persons to whom the |
// Software is furnished to do so, subject to the following conditions: |
// |
// The above copyright notice and this permission notice shall be |
// included in all copies or substantial portions of the Software. |
// |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
// OTHER DEALINGS IN THE SOFTWARE. |
//----------------------------------------------------------------------// |
|
module top; |
reg clk; |
reg rst_n; |
|
mkTestBench m(.CLK(clk),.RST_N(rst_n)); |
|
always@(clk) |
#5 clk <= ~clk; |
|
initial |
begin |
$dumpfile("dump.vcd"); |
$dumpvars(4,m); |
rst_n <= 0; |
clk <= 0; |
#50; |
rst_n <= 1; |
|
end |
|
|
|
endmodule |
/trunk/lib/bsv/BRAMFIFO/readme.txt
0,0 → 1,8
BRAM.bsv and BRAM.v are a bluespec wrapper for a synthesizable fpga BRAM. blue_sim_model directory contains a wholly bluespec cycle accurate model of the BRAM which can be used for simulation/debugging. |
|
These files were created by |
Kermin Fleming (MIT) |
Micheal Pellauer (MIT) |
Eric Chung (CMU) |
|
Caveat Codor. |
/trunk/lib/bsv/BRAMFIFO/BRAMFIFO.bsv
0,0 → 1,150
//----------------------------------------------------------------------// |
// The MIT License |
// |
// Copyright (c) 2008 Kermin Fleming, kfleming@mit.edu |
// |
// Permission is hereby granted, free of charge, to any person |
// obtaining a copy of this software and associated documentation |
// files (the "Software"), to deal in the Software without |
// restriction, including without limitation the rights to use, |
// copy, modify, merge, publish, distribute, sublicense, and/or sell |
// copies of the Software, and to permit persons to whom the |
// Software is furnished to do so, subject to the following conditions: |
// |
// The above copyright notice and this permission notice shall be |
// included in all copies or substantial portions of the Software. |
// |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
// OTHER DEALINGS IN THE SOFTWARE. |
//----------------------------------------------------------------------// |
|
import FIFO::*; |
import FIFOF::*; |
import FIFOF_::*; |
|
/*** |
* |
* This module serves as a simple bluespec wrapper for |
* the verilog based BRAMFIFO. The imported methods support |
* the standard FIFOF and FIFO classes. It should be noted that |
* the underlying verilog implementation is gaurded. |
* |
***/ |
|
|
module mkBRAMFIFO#(Integer count) (FIFO#(fifo_type)) |
provisos |
(Bits#(fifo_type, fifo_size)); |
FIFOF#(fifo_type) fifo <- mkBRAMFIFOF(count); |
|
method Action enq(fifo_type data); |
fifo.enq(data); |
endmethod |
|
method Action deq(); |
fifo.deq(); |
endmethod |
|
method fifo_type first(); |
return fifo.first(); |
endmethod |
|
method Action clear(); |
fifo.clear(); |
endmethod |
|
endmodule |
|
module mkBRAMFIFOF#(Integer count) (FIFOF#(fifo_type)) |
provisos |
(Bits#(fifo_type, fifo_size)); |
FIFOF_#(fifo_type) fifo <- mkBRAMFIFOF_(count); |
|
method Action enq(fifo_type data) if(fifo.i_notFull); |
fifo.enq(data); |
endmethod |
|
method Action deq() if(fifo.i_notEmpty); |
fifo.deq(); |
endmethod |
|
method fifo_type first() if(fifo.i_notEmpty); |
return fifo.first(); |
endmethod |
|
method Bool notFull; |
return fifo.notFull; |
endmethod |
|
method Bool notEmpty; |
return fifo.notEmpty; |
endmethod |
|
method Action clear(); |
fifo.clear(); |
endmethod |
|
|
endmodule |
|
|
import "BVI" BRAMFIFOF = module mkBRAMFIFOF_#(Integer count) |
//interface: |
(FIFOF_#(fifo_type)) |
provisos |
(Bits#(fifo_type, fifo_size)); |
|
default_clock clk(CLK); |
|
parameter log_data_count = log2(count); |
parameter data_count = count; |
parameter data_width = valueOf(fifo_size); |
|
method enq((* reg *)D_IN) enable(ENQ); |
method deq() enable(DEQ); |
method (* reg *)D_OUT first; |
method FULL_N notFull; |
method FULL_N i_notFull; |
method (* reg *)EMPTY_N notEmpty; |
method (* reg *)EMPTY_N i_notEmpty; |
method clear() enable(CLR); |
|
schedule deq CF (enq, i_notEmpty, i_notFull) ; |
schedule enq CF (deq, first, i_notEmpty, i_notFull) ; |
schedule (first, notEmpty, notFull) CF |
(first, i_notEmpty, i_notFull, notEmpty, notFull) ; |
schedule (i_notEmpty, i_notFull) CF |
(clear, first, i_notEmpty, i_notFull, notEmpty, notFull) ; |
schedule (clear, deq, enq) SBR clear ; |
schedule first SB (clear, deq) ; |
schedule (notEmpty, notFull) SB (clear, deq, enq) ; |
|
|
/*schedule first SB (deq,enq,clear); |
schedule first CF (first,notFull,notEmpty); |
|
schedule notFull SB (deq,enq,clear); |
schedule notFull CF (first,notFull,notEmpty); |
|
schedule notEmpty SB (deq,enq,clear); |
schedule notEmpty CF (first,notFull,notEmpty); |
|
schedule deq CF enq; |
schedule deq SB clear; |
schedule deq C deq; |
|
schedule enq CF deq; |
schedule enq SB clear; |
schedule enq C enq; |
|
schedule clear C clear;*/ |
|
endmodule |
|
|
/trunk/lib/bsv/Debug/Debug.bsv
0,0 → 1,7
function Action debug(Bool b, Action a); |
action |
|
if (b) a; |
|
endaction |
endfunction |
/trunk/lib/bsv/PLBMaster/build/Makefile
0,0 → 1,64
#/* |
#Copyright (c) 2008 MIT |
# |
#Permission is hereby granted, free of charge, to any person |
#obtaining a copy of this software and associated documentation |
#files (the "Software"), to deal in the Software without |
#restriction, including without limitation the rights to use, |
#copy, modify, merge, publish, distribute, sublicense, and/or sell |
#copies of the Software, and to permit persons to whom the |
#Software is furnished to do so, subject to the following |
#conditions: |
# |
#The above copyright notice and this permission notice shall be |
#included in all copies or substantial portions of the Software. |
# |
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
#EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
#OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
#NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
#HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
#WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
#FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
#OTHER DEALINGS IN THE SOFTWARE. |
# |
#Author: Kermin Fleming |
#*/ |
|
srcdir = ../src |
debugdir = ../../Debug |
testdir = ../test |
commondir = ../common |
bramdir = ../../BRAM/ |
feederdir = ../../BRAMFeeder/src |
fpgadir = ../fpga |
bdir = build/bdir |
vdir = build/vdir |
cdir = build/cdir |
simdir = build/simdir |
|
BSC = bsc |
|
VER_OPTS = +RTS -K100000000 --RTS -u -v -verilog -aggressive-conditions -vdir ./ |
SIM_OPTS = +RTS -K100000000 --RTS -u -v -sim -aggressive-conditions -show-schedule |
EXE_OPTS = +RTS -K100000000 --RTS -sim |
|
#-------------------------------------------------------------------- |
# Build targets |
#-------------------------------------------------------------------- |
|
build: |
mkdir -p build |
mkdir -p $(bdir) |
mkdir -p $(vdir) |
mkdir -p $(cdir) |
mkdir -p $(simdir) |
|
plbmaster : build |
$(BSC) $(VER_OPTS) -D PLB_DEFAULTS=0 -bdir $(bdir) -vdir $(vdir) -p +:$(srcdir):$(bramdir):$(debugdir):$(commondir):$(feederdir):$(bdir) -g mkPLBMaster $(srcdir)/PLBMaster.bsv > out.log |
|
plbtester_verilog : build |
$(BSC) $(VER_OPTS) -D PLB_DEFAULTS=0 -bdir $(bdir) -vdir $(vdir) -p +:$(srcdir):$(bramdir):$(debugdir):$(commondir):$(feederdir):$(bdir):$(fpgadir) -g mkPLBMasterTester $(fpgadir)/PLBMasterTester.bsv > out.log |
|
clean : |
rm -rf build |
/trunk/lib/bsv/PLBMaster/test/PLBMasterEmulator.bsv
0,0 → 1,120
/* |
This module is intended as an in-place model for a plb-based memory subsystem. |
This code was used in Memocode 08 design project. Memory size is |
given in 32 bit words. */ |
|
// CSG lib includes |
import PLBMaster::*; |
import PLBMasterWires::*; |
`ifdef PLB_DEFAULTS |
import PLBMasterDefaultParameters::*; |
`endif |
|
// BSC includes |
import Vector::*; |
import FIFO::*; |
import FIFOF::*; |
import GetPut::*; |
import RegFile::*; |
|
interface PLBMasterEmulator#(numeric type memorySize); |
interface PLBMaster plbmaster; |
endinterface |
|
typedef enum { |
Load, |
Store, |
Idle |
} State deriving (Bits, Eq); |
|
module mkPLBMasterEmulator#(RegFile#(Bit#(TLog#(memorySize)),BusWord) memory) (PLBMasterEmulator#(memorySize)) |
provisos(Add#(xxx,TLog#(memorySize),SizeOf#(BlockAddr))); |
Integer lineDelay = 14; |
|
Reg#(Bit#(TLog#(BeatsPerBurst))) plbCount <- mkReg(0); |
FIFOF#(BusWord) storeFIFO <- mkSizedFIFOF(valueof(BeatsPerBurst)); |
FIFOF#(PLBMasterCommand) plbLoadCommand <- mkFIFOF(); |
FIFOF#(PLBMasterCommand) plbStoreCommand <- mkFIFOF(); |
Reg#(Maybe#(Bit#(6))) plbDelay <- mkReg(tagged Invalid); |
Reg#(State) state <- mkReg(Idle); |
|
|
// Only start store if store is full |
rule startStoreDelay(plbDelay matches tagged Invalid &&& plbStoreCommand.notEmpty && !storeFIFO.notFull); |
state <= Store; |
plbDelay <= tagged Valid fromInteger(lineDelay); |
endrule |
|
rule startLoadDelay(plbDelay matches tagged Invalid &&& plbLoadCommand.notEmpty); |
state <= Load; |
plbDelay <= tagged Valid fromInteger(lineDelay); |
endrule |
|
rule tickCount(plbDelay matches tagged Valid .count &&& count > 0); |
plbDelay <= tagged Valid (count - 1); |
endrule |
|
rule storeRule(plbStoreCommand.first matches tagged StorePage .addr &&& plbDelay matches tagged Valid .count &&& count == 0 &&& (state == Store)); |
Bit#(64) wordInput = storeFIFO.first; |
// The addr refers to 32 bit addresses |
Bit#(TLog#(memorySize)) addrMod = truncate((addr>>1)+ zeroExtend(plbCount)); |
|
storeFIFO.deq; |
memory.upd(addrMod,wordInput); |
$display("plbMaster store count: %d, mem[%d] <= %h",plbCount, addrMod, storeFIFO.first); |
plbCount <= plbCount + 1; |
if(plbCount + 1 == 0) |
begin |
state <= Idle; |
plbDelay <= tagged Invalid; |
plbStoreCommand.deq; |
end |
endrule |
|
interface PLBMaster plbmaster; |
|
interface Put wordInput; |
method Action put(Bit#(64) wordInput); |
storeFIFO.enq(wordInput); |
endmethod |
endinterface |
|
interface Get wordOutput; |
method ActionValue#(Bit#(64)) get() if(plbLoadCommand.first matches tagged LoadPage .addr &&& plbDelay matches tagged Valid .count &&& count == 0 &&& (state == Load)); |
plbCount <= plbCount + 1; |
|
if(plbCount + 1 == 0) |
begin |
$display("plbMaster load command dequed!"); |
plbLoadCommand.deq; |
state <= Idle; |
plbDelay <= tagged Invalid; |
end |
// This may not be correct. |
Bit#(TLog#(memorySize)) addrMod = truncate((addr>>1) + zeroExtend(plbCount)); |
$display("plbMaster load count: %d, mem[%d]: %h",plbCount, addrMod, memory.sub(addrMod)); |
return memory.sub(addrMod); |
endmethod |
endinterface |
|
interface Put plbMasterCommandInput; |
method Action put(PLBMasterCommand command); |
$display("PLB Master got a command: %s", command matches tagged LoadPage .addr?"Load":"Store"); |
if(command matches tagged StorePage .addr) |
begin |
plbStoreCommand.enq(command); |
end |
else |
begin |
plbLoadCommand.enq(command); |
end |
endmethod |
endinterface |
|
interface plbMasterWires = ?; |
|
endinterface |
|
|
|
endmodule |
/trunk/lib/bsv/PLBMaster/src/PLBMaster.bsv
0,0 → 1,545
/* |
Copyright (c) 2007 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Kermin Fleming |
*/ |
|
/* This file implements a PLB bus master. The bus master operates on static |
sized bursts. It is written in such a way that read/write bursts may be |
overlapped, if the bus and target slave support such a feature. There's also |
support for pipelining of read and write requests. The master is |
parameterized by BeatsPerBurst (burst length) and BusWord (bus width), |
which allow it to be used for various applications. |
*/ |
|
// Global Imports |
import GetPut::*; |
import FIFO::*; |
import RegFile::*; |
import BRAMInitiatorWires::*; |
import RegFile::*; |
import FIFOF::*; |
import Vector::*; |
`ifdef PLB_DEFAULTS |
import PLBMasterDefaultParameters::*; |
`endif |
|
import PLBMasterWires::*; |
|
typedef Bit#(30) BlockAddr; |
|
interface PLBMaster; |
interface Put#(Bit#(64)) wordInput; |
interface Get#(Bit#(64)) wordOutput; |
interface Put#(PLBMasterCommand) plbMasterCommandInput; |
interface PLBMasterWires plbMasterWires; |
endinterface |
|
typedef union tagged |
{ |
BlockAddr LoadPage; |
BlockAddr StorePage; |
} |
PLBMasterCommand |
deriving(Bits,Eq); |
|
typedef enum { |
Idle, |
Data, |
WaitForBusy |
} StateTransfer |
deriving(Bits, Eq); |
|
typedef enum { |
Idle, |
RequestingLoad, |
RequestingStore |
} StateRequest |
deriving(Bits, Eq); |
|
(* synthesize *) |
module mkPLBMaster (PLBMaster); |
Clock plbClock <- exposeCurrentClock(); |
Reset plbReset <- exposeCurrentReset(); |
// state for the actual magic memory hardware |
FIFO#(BusWord) recordInfifo <- mkFIFO; |
FIFO#(BusWord) recordOutfifo <- mkFIFO; |
FIFO#(PLBMasterCommand) plbMasterCommandInfifo <- mkFIFO(); |
|
|
// Output buffer |
RegFile#(Bit#(TAdd#(1,TLog#(BeatsPerBurst))),BusWord) storeBuffer <- mkRegFileFull(); |
|
|
// Input buffer |
RegFile#(Bit#(TAdd#(1,TLog#(BeatsPerBurst))),BusWord) loadBuffer <- mkRegFileFull(); |
|
|
Reg#(Bit#(24)) rowAddrOffsetLoad <- mkReg(0); |
Reg#(Bit#(24)) rowAddrOffsetStore <- mkReg(0); |
|
Reg#(Bool) doingLoad <- mkReg(False); |
Reg#(Bool) doingStore <- mkReg(False); |
|
Bit#(TLog#(TMul#(BeatsPerBurst, WordsPerBeat))) zeroOffset = 0; // Words per Burst |
Reg#(Bool) requestingStore <- mkReg(False); |
BlockAddr addressOffset = zeroExtend({(requestingStore)?rowAddrOffsetStore:rowAddrOffsetLoad,zeroOffset}); |
|
|
Reg#(StateRequest) stateRequest <- mkReg(Idle); |
Reg#(StateTransfer) stateLoad <- mkReg(Idle); |
Reg#(StateTransfer) stateStore <- mkReg(Idle); |
Reg#(Bit#(1)) request <- mkReg(0); |
Reg#(Bit#(1)) rnw <- mkReg(0); |
|
|
Reg#(Bit#(TLog#(BeatsPerBurst))) loadDataCount <- mkReg(0); |
Reg#(Bit#(TLog#(BeatsPerBurst))) storeDataCount <-mkReg(0);// If you change this examine mWrDBus_o |
Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst)))) loadDataCount_plus2 <- mkReg(2); |
Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst)))) storeDataCount_plus2 <-mkReg(2); |
|
Reg#(Bool) doAckinIdle <- mkReg(False); |
|
Reg#(Bit#(1)) rdBurst <- mkReg(0); |
Reg#(Bit#(1)) wrBurst <- mkReg(0); |
|
Reg#(Bit#(1)) storeCounter <- mkReg(0); |
Reg#(Bit#(1)) loadCounter <- mkReg(0); |
|
Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst)))) storeBufferWritePointer <- mkReg(0); |
FIFOF#(Bit#(0)) storeValid <- mkUGFIFOF;//XXX: This could be bad |
Reg#(Bit#(TAdd#(1,TLog#(BeatsPerBurst)))) loadBufferReadPointer <- mkReg(0); |
FIFOF#(Bit#(0)) loadValid <- mkUGFIFOF;//XXX: This could be bad |
|
|
// Input wires |
Wire#(Bit#(1)) mRst <- mkBypassWire(); |
Wire#(Bit#(1)) mAddrAck <- mkBypassWire(); |
Wire#(Bit#(1)) mBusy <- mkBypassWire(); |
Wire#(Bit#(1)) mErr <- mkBypassWire(); |
Wire#(Bit#(1)) mRdBTerm <- mkBypassWire(); |
Wire#(Bit#(1)) mRdDAck <- mkBypassWire(); |
Wire#(Bit#(64))mRdDBus <- mkBypassWire(); |
Wire#(Bit#(3)) mRdWdAddr <- mkBypassWire(); |
Wire#(Bit#(1)) mRearbitrate <- mkBypassWire(); |
Wire#(Bit#(1)) mWrBTerm <- mkBypassWire(); |
Wire#(Bit#(1)) mWrDAck <- mkBypassWire(); |
Wire#(Bit#(1)) mSSize <- mkBypassWire(); |
Wire#(Bit#(1)) sMErr <- mkBypassWire(); // on a read, during the data ack |
Wire#(Bit#(1)) sMBusy <- mkBypassWire(); |
|
// Outputs |
|
|
Bit#(PLBAddrSize) mABus_o = {addressOffset,2'b00}; // Our address Address Bus, we extend to compensate for word |
|
|
Bit#(TAdd#(1,TLog#(BeatsPerBurst))) sbuf_addr = {storeCounter,storeDataCount}; |
|
|
Bit#(64)mWrDBus_o = storeBuffer.sub(sbuf_addr); |
Bit#(1) mRequest_o = request & ~mRst; // Request |
Bit#(1) mBusLock_o = 1'b0 & ~mRst; // Bus lock |
Bit#(1) mRdBurst_o = rdBurst & ~mRst; // read burst |
Bit#(1) mWrBurst_o = wrBurst & ~mRst; // write burst |
Bit#(1) mRNW_o = rnw; // Read Not Write |
Bit#(1) mAbort_o = 1'b0; // Abort |
Bit#(2) mPriority_o = 2'b11;// priority indicator |
Bit#(1) mCompress_o = 1'b0;// compressed transfer |
Bit#(1) mGuarded_o = 1'b0;// guarded transfer |
Bit#(1) mOrdered_o = 1'b0;// synchronize transfer |
Bit#(1) mLockErr_o = 1'b0;// lock erro |
Bit#(4) mSize_o = 4'b1011; // Burst double word transfer - see PLB p.24 |
Bit#(3) mType_o = 3'b000; // Memory Transfer |
Bit#(8) mBE_o = 8'b00001111; // 16 word burst |
Bit#(2) mMSize_o = 2'b00; |
|
|
// precompute the next address offset. Sometimes |
|
|
PLBMasterCommand cmd_in_first = plbMasterCommandInfifo.first(); |
|
let newloadDataCount = loadDataCount + 1; |
let newstoreDataCount = storeDataCount + 1; |
let newloadDataCount_plus2 = loadDataCount_plus2 + 1; |
let newstoreDataCount_plus2 = storeDataCount_plus2 + 1; |
|
|
rule startPageLoad(cmd_in_first matches tagged LoadPage .ba &&& !doingLoad); |
$display("Start Page"); |
plbMasterCommandInfifo.deq(); |
$display("Load Page"); |
rowAddrOffsetLoad <= truncate(ba>>(valueof(TLog#(TMul#(BeatsPerBurst, WordsPerBeat))))); // this is the log |
if (ba[3:0] != 0) |
$display("ERROR:Address not 64-byte aligned"); |
doingLoad <= True; |
endrule |
|
rule startPageStore(cmd_in_first matches tagged StorePage .ba &&& !doingStore); |
$display("Start Page"); |
plbMasterCommandInfifo.deq(); |
$display("Store Page"); |
rowAddrOffsetStore <= truncate(ba>>(valueof(TLog#(TMul#(BeatsPerBurst, WordsPerBeat))))); // this is the log |
// size of burst addr |
if (ba[3:0] != 0) |
$display("ERROR:Address not 64-byte aligned"); |
doingStore <= True; |
endrule |
|
|
rule loadPage_Idle(doingLoad && stateRequest == Idle && stateLoad == Idle); |
// We should not initiate a transfer if the wordOutfifo is not valid |
//$display("loadPage_Idle"); |
requestingStore <= False; |
if(loadValid.notFull())// Check for a spot. |
begin |
request <= 1'b1; |
stateRequest <= RequestingLoad; |
end |
else |
begin |
request <= 1'b0; // Not Sure this is needed |
end |
|
rnw <= 1'b1; // We're reading |
endrule |
|
|
|
rule loadPage_Requesting(doingLoad && stateRequest == RequestingLoad && stateLoad == Idle); |
// We've just requested the bus and are waiting for an ack |
//$display("loadPage_Requesting"); |
if(mAddrAck == 1 ) |
begin |
stateRequest <= Idle; |
// Check for error conditions |
if(mRearbitrate == 1) |
begin |
// Got terminated by the bus |
$display("Terminated by BUS @ %d",$time); |
stateLoad <= Idle; |
rdBurst <= 1'b0; // if we're rearbing this should be off. It may be off anyway? |
request <= 1'b0; |
end |
else |
begin |
//Whew! didn't die yet.. wait for acks to come back |
stateLoad <= Data; |
// Not permissible to assert burst until after addrAck p. 35 |
rdBurst <= 1'b1; |
// Set down request, as we are not request pipelining |
request <= 1'b0; |
end |
end |
endrule |
|
rule loadPage_Data(doingLoad && stateLoad == Data); |
if(((mRdBTerm == 1) && (loadDataCount_plus2 < (fromInteger(valueof(BeatsPerBurst))))) || (mErr == 1)) |
begin |
// We got terminated / Errored |
rdBurst <= 1'b0; |
loadDataCount <= 0; |
loadDataCount_plus2 <= 2; |
stateLoad <= Idle; |
end |
else if(mRdDAck == 1) |
begin |
loadDataCount <= newloadDataCount; |
loadDataCount_plus2 <= newloadDataCount_plus2; |
loadBuffer.upd({loadCounter,loadDataCount}, mRdDBus); |
if(newloadDataCount == 0) |
begin |
loadCounter <= loadCounter + 1; // Flip the loadCounter |
//We're now done reading... what should we do? |
loadValid.enq(0); // This signifies that the data is valid Nirav could probably remove this |
doingLoad <= False; |
stateLoad <= Idle; |
end |
else if(newloadDataCount == maxBound) // YYY: ndave used to ~0 |
begin |
// Last read is upcoming. Need to set down the |
// rdBurst signal. |
rdBurst <= 1'b0; |
end |
end |
endrule |
|
|
|
rule storePage_Idle(doingStore && stateRequest == Idle && stateStore == Idle); |
requestingStore <= True; |
if(storeValid.notEmpty()) |
begin |
request <= 1'b1; |
stateRequest <= RequestingStore; |
end |
else |
begin |
request <= 1'b0; |
end |
|
wrBurst <= 1'b1; // Write burst is asserted with the write request |
rnw <= 1'b0; // We're writing |
endrule |
|
rule storePage_Requesting(doingStore && stateRequest == RequestingStore && stateStore == Idle); |
// We've just requested the bus and are waiting for an ack |
if(mAddrAck == 1 ) |
begin |
stateRequest <= Idle; |
// Check for error conditions |
if(mRearbitrate == 1) |
begin |
// Got terminated by the bus |
wrBurst <= 1'b0; |
request <= 1'b0; |
end |
else |
begin |
// Set down request, as we are not request pipelining |
request <= 1'b0; |
// We can be WrDAck'ed at this time p.29 or WrBTerm p.30 |
if(mWrBTerm == 1) |
begin |
wrBurst <= 1'b0; |
end |
else if(mWrDAck == 1) |
begin |
storeDataCount <= newstoreDataCount; |
storeDataCount_plus2 <= newstoreDataCount_plus2; |
stateStore <= Data; |
end |
else |
begin |
stateStore <= Data; |
end |
end |
end |
endrule |
|
|
rule storePage_Data(doingStore && stateStore == Data); |
if((mWrBTerm == 1) && (storeDataCount_plus2 < (fromInteger(valueof(BeatsPerBurst)))) || (mErr == 1)) |
begin |
// We got terminated / Errored |
wrBurst <= 1'b0; |
storeDataCount <= 0; |
storeDataCount_plus2 <= 2; |
stateStore <= Idle; // Can't burst for a cycle p. 30 |
end |
else if(mWrDAck == 1) |
begin |
storeDataCount <= newstoreDataCount; |
storeDataCount_plus2 <= newstoreDataCount_plus2; |
if(newstoreDataCount == 0) |
begin |
//We're now done reading... what should we do? |
// Data transfer complete |
if(mBusy == 0) |
begin |
doingStore <= False; |
stateStore <= Idle; |
storeValid.deq(); |
storeCounter <= storeCounter + 1; |
end |
else |
begin |
stateStore <= WaitForBusy; |
end |
end |
else if(newstoreDataCount == maxBound) //YYY: used to be ~0 |
begin |
// Last read is upcoming. Need to set down the |
// wrBurst signal. |
wrBurst <= 1'b0; |
end |
end |
endrule |
|
rule storePage_WaitForBusy(doingStore && stateStore == WaitForBusy); |
if(mErr == 1) |
begin |
// We got terminated / Errored |
wrBurst <= 1'b0; |
storeDataCount <= 0; // may not be necessary |
storeDataCount_plus2 <= 2; |
stateStore <= Idle; // Can't burst for a cycle p. 30 |
end |
else if(mBusy == 0) |
begin |
storeCounter <= storeCounter + 1; |
doingStore <= False; |
stateStore <= Idle; |
storeValid.deq(); |
end |
endrule |
|
/******** |
/* Code For Handling Record Translation |
/*******/ |
|
rule writeStoreData(storeValid.notFull()); |
storeBufferWritePointer <= storeBufferWritePointer + 1; |
|
|
storeBuffer.upd(storeBufferWritePointer, {recordInfifo.first[31:0] ,recordInfifo.first[63:32]}); |
|
|
recordInfifo.deq; |
|
Bit#(TLog#(BeatsPerBurst)) bottomValue = 0; |
if(truncate(storeBufferWritePointer + 1) == bottomValue) |
begin |
$display("Store Data finished a flight"); |
storeValid.enq(0); |
end |
endrule |
|
|
rule wordToRecord(loadValid.notEmpty()); |
loadBufferReadPointer <= loadBufferReadPointer + 1; |
Bit#(64) loadValue = loadBuffer.sub(loadBufferReadPointer); |
Bit#(32) loadHigh = loadValue [63:32]; |
Bit#(32) loadLow = loadValue [31:0]; |
Bit#(TLog#(BeatsPerBurst)) bottomValue = 0; |
if(truncate(loadBufferReadPointer + 1) == bottomValue) |
begin |
$display("Load Data finished a flight"); |
loadValid.deq(); |
end |
|
|
recordOutfifo.enq({loadLow,loadHigh}); |
|
endrule |
|
interface Put wordInput = fifoToPut(recordInfifo); |
|
interface Get wordOutput = fifoToGet(recordOutfifo); |
|
interface Put plbMasterCommandInput = fifoToPut(plbMasterCommandInfifo); |
|
|
interface PLBMasterWires plbMasterWires; |
|
method Bit#(PLBAddrSize) mABus(); // Address Bus |
return mABus_o; |
endmethod |
method Bit#(8) mBE(); // Byte Enable |
return mBE_o; |
endmethod |
|
method Bit#(1) mRNW(); // Read Not Write |
return mRNW_o; |
endmethod |
|
method Bit#(1) mAbort(); // Abort |
return mAbort_o; |
endmethod |
|
method Bit#(1) mBusLock(); // Bus lock |
return mBusLock_o; |
endmethod |
|
method Bit#(1) mCompress(); // compressed transfer |
return mCompress_o; |
endmethod |
|
method Bit#(1) mGuarded(); // guarded transfer |
return mGuarded_o; |
endmethod |
|
method Bit#(1) mLockErr(); // lock error |
return mLockErr_o; |
endmethod |
|
method Bit#(2) mMSize(); // data bus width? |
return mMSize_o; |
endmethod |
|
method Bit#(1) mOrdered(); // synchronize transfer |
return mOrdered_o; |
endmethod |
|
method Bit#(2) mPriority(); // priority indicator |
return mPriority_o; |
endmethod |
|
method Bit#(1) mRdBurst(); // read burst |
return mRdBurst_o; |
endmethod |
|
method Bit#(1) mRequest(); // bus request |
return mRequest_o; |
endmethod |
|
method Bit#(4) mSize(); // transfer size |
return mSize_o; |
endmethod |
|
method Bit#(3) mType(); // transfer type (dma) |
return mType_o; |
endmethod |
|
method Bit#(1) mWrBurst(); // write burst |
return mWrBurst_o; |
endmethod |
|
method Bit#(64) mWrDBus(); // write data bus |
return mWrDBus_o; |
endmethod |
|
method Action plbIN( |
Bit#(1) mRst_in, // PLB reset |
Bit#(1) mAddrAck_in, // Addr Ack |
Bit#(1) mBusy_in, // Master Busy |
Bit#(1) mErr_in, // Slave Error |
Bit#(1) mRdBTerm_in, // Read burst terminate signal |
Bit#(1) mRdDAck_in, // Read data ack |
Bit#(64)mRdDBus_in, // Read data bus |
Bit#(3) mRdWdAddr_in, // Read word address |
Bit#(1) mRearbitrate_in, // Rearbitrate |
Bit#(1) mWrBTerm_in, // Write burst terminate |
Bit#(1) mWrDAck_in, // Write data ack |
Bit#(1) mSSize_in, // Slave bus size |
Bit#(1) sMErr_in, // Slave error |
Bit#(1) sMBusy_in); // Slave busy |
mRst <= mRst_in; |
mAddrAck <= mAddrAck_in; |
mBusy <= mBusy_in; |
mErr <= mErr_in; |
mRdBTerm <= mRdBTerm_in; |
mRdDAck <= mRdDAck_in; |
mRdDBus <= mRdDBus_in; |
mRdWdAddr <= mRdWdAddr_in; |
mRearbitrate <= mRearbitrate_in; |
mWrBTerm <= mWrBTerm_in; |
mWrDAck <= mWrDAck_in; |
mSSize <= mSSize_in; |
sMErr <= sMErr_in; |
sMBusy <= sMBusy_in; |
endmethod |
endinterface |
endmodule |
/trunk/lib/bsv/PLBMaster/src/PLBMasterWires.bsv
0,0 → 1,142
/* |
Copyright (c) 2007 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Kermin Fleming |
*/ |
|
// Global Imports |
import GetPut::*; |
|
// We only use the default params if the compile flag is turned on. |
`ifdef PLB_DEFAULTS |
import PLBMasterDefaultParameters::*; |
`endif |
|
`define PLB_CLK_NAME "mClk" |
`define PLB_RST_NAME "mRst" |
`define PLB_COMPRESS_NAME "mCompress" |
`define PLB_ABUS_NAME "mABus" |
`define PLB_BE_NAME "mBE" |
`define PLB_RNW_NAME "mRNW" |
`define PLB_ABORT_NAME "mAbort" |
`define PLB_BUSLOCK_NAME "mBusLock" |
`define PLB_PRESS_NAME "mpress" |
`define PLB_GUARDED_NAME "mGuarded" |
`define PLB_LOCKERR_NAME "mLockErr" |
`define PLB_MSIZE_NAME "mMSize" |
`define PLB_ORDERED_NAME "mOrdered" |
`define PLB_PRIORITY_NAME "mPriority" |
`define PLB_RDBURST_NAME "mRdBurst" |
`define PLB_REQUEST_NAME "mRequest" |
`define PLB_SIZE_NAME "mSize" |
`define PLB_TYPE_NAME "mType" |
`define PLB_WRBURST_NAME "mWrBurst" |
`define PLB_WRDBUS_NAME "mWrDBus" |
`define PLB_MADDRACK_NAME "mAddrAck" |
`define PLB_MBUSY_NAME "mBusy" |
`define PLB_MERR_NAME "mErr" |
`define PLB_MRDBTERM_NAME "mRdBTerm" |
`define PLB_MRDDACK_NAME "mRdDAck" |
`define PLB_MRDDBUS_NAME "mRdDBus" |
`define PLB_MRDWDADDR_NAME "mRdWdAddr" |
`define PLB_MREARBITRATE_NAME "mRearbitrate" |
`define PLB_MWRBTERM_NAME "mWrBTerm" |
`define PLB_MWRDACK_NAME "mWrDAck" |
`define PLB_MSSIZE_NAME "mSSize" |
`define PLB_SMERR_NAME "sMErr" |
`define PLB_SMBUSY_NAME "sMBusy" |
|
|
interface PLBMasterWires; |
|
(* always_ready, prefix="", result=`PLB_ABUS_NAME *) |
method Bit#(PLBAddrSize) mABus(); // Address Bus |
|
(* always_ready, prefix="", result=`PLB_BE_NAME *) |
method Bit#(8) mBE(); // Byte Enable |
|
(* always_ready, prefix="", result=`PLB_RNW_NAME *) |
method Bit#(1) mRNW(); // Read Not Write |
|
(* always_ready, prefix="", result=`PLB_ABORT_NAME *) |
method Bit#(1) mAbort(); // Abort |
|
(* always_ready, prefix="", result=`PLB_BUSLOCK_NAME *) |
method Bit#(1) mBusLock(); // Bus lock |
|
(* always_ready, prefix="", result=`PLB_COMPRESS_NAME *) |
method Bit#(1) mCompress(); // compressed transfer |
|
(* always_ready, prefix="", result=`PLB_GUARDED_NAME *) |
method Bit#(1) mGuarded(); // guarded transfer |
|
(* always_ready, prefix="", result=`PLB_LOCKERR_NAME *) |
method Bit#(1) mLockErr(); // lock error |
|
(* always_ready, prefix="", result=`PLB_MSIZE_NAME *) |
method Bit#(2) mMSize(); // data bus width? |
|
(* always_ready, prefix="", result=`PLB_ORDERED_NAME *) |
method Bit#(1) mOrdered(); // synchronize transfer |
|
(* always_ready, prefix="", result=`PLB_PRIORITY_NAME *) |
method Bit#(2) mPriority(); // priority indicator |
|
(* always_ready, prefix="", result=`PLB_RDBURST_NAME *) |
method Bit#(1) mRdBurst(); // read burst |
|
(* always_ready, prefix="", result=`PLB_REQUEST_NAME *) |
method Bit#(1) mRequest(); // bus request |
|
(* always_ready, prefix="", result=`PLB_SIZE_NAME *) |
method Bit#(4) mSize(); // transfer size |
|
(* always_ready, prefix="", result=`PLB_TYPE_NAME *) |
method Bit#(3) mType(); // transfer type (dma) |
|
(* always_ready, prefix="", result=`PLB_WRBURST_NAME *) |
method Bit#(1) mWrBurst(); // write burst |
|
(* always_ready, prefix="", result=`PLB_WRDBUS_NAME *) |
method Bit#(64) mWrDBus(); // write data bus |
|
(* always_ready, prefix="", always_enabled *) |
method Action plbIN( |
(* port=`PLB_RST_NAME *) Bit#(1) mRst, // PLB reset |
(* port=`PLB_MADDRACK_NAME *) Bit#(1) mAddrAck, // Addr Ack |
(* port=`PLB_MBUSY_NAME *) Bit#(1) mBusy, // Master Busy |
(* port=`PLB_MERR_NAME *) Bit#(1) mErr, // Slave Error |
(* port=`PLB_MRDBTERM_NAME *) Bit#(1) mRdBTerm, // Read burst terminate signal |
(* port=`PLB_MRDDACK_NAME *) Bit#(1) mRdDAck, // Read data ack |
(* port=`PLB_MRDDBUS_NAME *) Bit#(64)mRdDBus, // Read data bus |
(* port=`PLB_MRDWDADDR_NAME *) Bit#(3) mRdWdAddr, // Read word address |
(* port=`PLB_MREARBITRATE_NAME *) Bit#(1) mRearbitrate, // Rearbitrate |
(* port=`PLB_MWRBTERM_NAME *) Bit#(1) mWrBTerm, // Write burst terminate |
(* port=`PLB_MWRDACK_NAME *) Bit#(1) mWrDAck, // Write data ack |
(* port=`PLB_MSSIZE_NAME *) Bit#(1) mSSize, // Slave bus size |
(* port=`PLB_SMERR_NAME *) Bit#(1) sMErr, // Slave error |
(* port=`PLB_SMBUSY_NAME *) Bit#(1) sMBusy); // Slave busy |
|
|
endinterface |
/trunk/lib/bsv/PLBMaster/common/PLBMasterDefaultParameters.bsv
0,0 → 1,7
typedef 32 PLBAddrSize; |
typedef Bit#(PLBAddrSize) PLBAddr; |
typedef 2 WordsPerBeat; // PLB bandwidth |
typedef 16 BurstSize; // number of beats per burst |
typedef 16 BeatsPerBurst; |
typedef Bit#(64) BusWord; |
typedef TMul#(WordsPerBeat,BeatsPerBurst) WordsPerBurst; |
/trunk/lib/bsv/PLBMaster/fpga/plbmastertester.v
0,0 → 1,234
/* |
Copyright (c) 2007 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Nirav Dave |
*/ |
|
module plbmastertester(CLK, |
RST, |
|
plbMasterWires_mABus, |
|
plbMasterWires_mBE, |
|
plbMasterWires_mRNW, |
|
plbMasterWires_mAbort, |
|
plbMasterWires_mBusLock, |
|
plbMasterWires_mCompress, |
|
plbMasterWires_mGuarded, |
|
plbMasterWires_mLockErr, |
|
plbMasterWires_mMSize, |
|
plbMasterWires_mOrdered, |
|
plbMasterWires_mPriority, |
|
plbMasterWires_mRdBurst, |
|
plbMasterWires_mRequest, |
|
plbMasterWires_mSize, |
|
plbMasterWires_mType, |
|
plbMasterWires_mWrBurst, |
|
plbMasterWires_mWrDBus, |
|
plbMasterWires_mRst, |
plbMasterWires_mAddrAck, |
plbMasterWires_mBusy, |
plbMasterWires_mErr, |
plbMasterWires_mRdBTerm, |
plbMasterWires_mRdDAck, |
plbMasterWires_mRdDBus, |
plbMasterWires_mRdWdAddr, |
plbMasterWires_mRearbitrate, |
plbMasterWires_mWrBTerm, |
plbMasterWires_mWrDAck, |
plbMasterWires_mSSize, |
plbMasterWires_sMErr, |
plbMasterWires_sMBusy, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramDin); |
input CLK; |
input RST; |
|
// value method plbMasterWires_mABus |
output [31 : 0] plbMasterWires_mABus; |
|
// value method plbMasterWires_mBE |
output [7 : 0] plbMasterWires_mBE; |
|
// value method plbMasterWires_mRNW |
output plbMasterWires_mRNW; |
|
// value method plbMasterWires_mAbort |
output plbMasterWires_mAbort; |
|
// value method plbMasterWires_mBusLock |
output plbMasterWires_mBusLock; |
|
// value method plbMasterWires_mCompress |
output plbMasterWires_mCompress; |
|
// value method plbMasterWires_mGuarded |
output plbMasterWires_mGuarded; |
|
// value method plbMasterWires_mLockErr |
output plbMasterWires_mLockErr; |
|
// value method plbMasterWires_mMSize |
output [1 : 0] plbMasterWires_mMSize; |
|
// value method plbMasterWires_mOrdered |
output plbMasterWires_mOrdered; |
|
// value method plbMasterWires_mPriority |
output [1 : 0] plbMasterWires_mPriority; |
|
// value method plbMasterWires_mRdBurst |
output plbMasterWires_mRdBurst; |
|
// value method plbMasterWires_mRequest |
output plbMasterWires_mRequest; |
|
// value method plbMasterWires_mSize |
output [3 : 0] plbMasterWires_mSize; |
|
// value method plbMasterWires_mType |
output [2 : 0] plbMasterWires_mType; |
|
// value method plbMasterWires_mWrBurst |
output plbMasterWires_mWrBurst; |
|
// value method plbMasterWires_mWrDBus |
output [63 : 0] plbMasterWires_mWrDBus; |
|
// action method plbMasterWires_plbIN |
input plbMasterWires_mRst; |
input plbMasterWires_mAddrAck; |
input plbMasterWires_mBusy; |
input plbMasterWires_mErr; |
input plbMasterWires_mRdBTerm; |
input plbMasterWires_mRdDAck; |
input [63 : 0] plbMasterWires_mRdDBus; |
input [2 : 0] plbMasterWires_mRdWdAddr; |
input plbMasterWires_mRearbitrate; |
input plbMasterWires_mWrBTerm; |
input plbMasterWires_mWrDAck; |
input plbMasterWires_mSSize; |
input plbMasterWires_sMErr; |
input plbMasterWires_sMBusy; |
|
// action method bramTargetWires_bramIN |
output [31 : 0] bramInitiatorWires_bramAddr; |
output [31 : 0] bramInitiatorWires_bramDout; |
output [3 : 0] bramInitiatorWires_bramWEN; |
output bramInitiatorWires_bramEN; |
output bramInitiatorWires_bramCLK; |
output bramInitiatorWires_bramRST; |
|
// value method bramTargetWires_bramOUT |
input [31 : 0] bramInitiatorWires_bramDin; |
|
wire [13:0] bramInitiatorWires_bramAddr_our; |
assign bramInitiatorWires_bramAddr = {16'h00000,bramInitiatorWires_bramAddr_our, 2'b00}; |
// signals for module outputs |
wire [31 : 0] bramTargetWires_dinBRAM,plbMasterWires_mABus; |
|
wire [63 : 0] plbMasterWires_mWrDBus; |
wire [7 : 0] plbMasterWires_mBE; |
wire [3 : 0] plbMasterWires_mSize; |
wire [2 : 0] plbMasterWires_mType; |
wire [1 : 0] plbMasterWires_mMSize, plbMasterWires_mPriority; |
wire plbMasterWires_mAbort, |
plbMasterWires_mBusLock, |
plbMasterWires_mCompress, |
plbMasterWires_mGuarded, |
plbMasterWires_mLockErr, |
plbMasterWires_mOrdered, |
plbMasterWires_mRNW, |
plbMasterWires_mRdBurst, |
plbMasterWires_mRequest, |
plbMasterWires_mWrBurst; |
|
wire RST_N; |
assign RST_N = ~RST; |
|
mkPLBMasterTester m( |
.CLK(CLK), |
.RST_N(RST_N), |
.plbMasterWires_mABus(plbMasterWires_mABus), |
.plbMasterWires_mBE(plbMasterWires_mBE), |
.plbMasterWires_mRNW(plbMasterWires_mRNW), |
.plbMasterWires_mAbort(plbMasterWires_mAbort), |
.plbMasterWires_mBusLock(plbMasterWires_mBusLock), |
.plbMasterWires_mCompress(plbMasterWires_mCompress), |
.plbMasterWires_mGuarded(plbMasterWires_mGuarded), |
.plbMasterWires_mLockErr(plbMasterWires_mLockErr), |
.plbMasterWires_mMSize(plbMasterWires_mMSize), |
.plbMasterWires_mOrdered(plbMasterWires_mOrdered), |
.plbMasterWires_mPriority(plbMasterWires_mPriority), |
.plbMasterWires_mRdBurst(plbMasterWires_mRdBurst), |
.plbMasterWires_mRequest(plbMasterWires_mRequest), |
.plbMasterWires_mSize(plbMasterWires_mSize), |
.plbMasterWires_mType(plbMasterWires_mType), |
.plbMasterWires_mWrBurst(plbMasterWires_mWrBurst), |
.plbMasterWires_mWrDBus(plbMasterWires_mWrDBus), |
.plbMasterWires_mRst(plbMasterWires_mRst), |
.plbMasterWires_mAddrAck(plbMasterWires_mAddrAck), |
.plbMasterWires_mBusy(plbMasterWires_mBusy), |
.plbMasterWires_mErr(plbMasterWires_mErr), |
.plbMasterWires_mRdBTerm(plbMasterWires_mRdBTerm), |
.plbMasterWires_mRdDAck(plbMasterWires_mRdDAck), |
.plbMasterWires_mRdDBus(plbMasterWires_mRdDBus), |
.plbMasterWires_mRdWdAddr(plbMasterWires_mRdWdAddr), |
.plbMasterWires_mRearbitrate(plbMasterWires_mRearbitrate), |
.plbMasterWires_mWrBTerm(plbMasterWires_mWrBTerm), |
.plbMasterWires_mWrDAck(plbMasterWires_mWrDAck), |
.plbMasterWires_mSSize(plbMasterWires_mSSize), |
.plbMasterWires_sMErr(plbMasterWires_sMErr), |
.plbMasterWires_sMBusy(plbMasterWires_sMBusy), |
.bramInitiatorWires_bramAddr(bramInitiatorWires_bramAddr_our), |
.bramInitiatorWires_bramDout(bramInitiatorWires_bramDout), |
.bramInitiatorWires_bramWEN(bramInitiatorWires_bramWEN), |
.bramInitiatorWires_bramEN(bramInitiatorWires_bramEN), |
.bramInitiatorWires_bramCLK(bramInitiatorWires_bramCLK), |
.bramInitiatorWires_bramRST(bramInitiatorWires_bramRST), |
.bramInitiatorWires_din(bramInitiatorWires_bramDin) |
); |
|
endmodule |
/trunk/lib/bsv/PLBMaster/fpga/PLBMasterTester.bsv
0,0 → 1,102
/* |
Copyright (c) 2008 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Kermin Fleming |
*/ |
|
import PLBMasterWires::*; |
import BRAMInitiatorWires::*; |
import PLBMaster::*; |
import BRAMFeeder::*; |
import PLBMasterDefaultParameters::*; |
import FIFO::*; |
import GetPut::*; |
|
interface PLBMasterTester; |
interface PLBMasterWires plbMasterWires; |
interface BRAMInitiatorWires#(Bit#(14)) bramInitiatorWires; |
endinterface |
|
typedef enum{ |
Idle, |
Running, |
Inputing, |
Outputing |
} TesterState deriving (Bits,Eq); |
|
|
module mkPLBMasterTester(PLBMasterTester); |
Feeder feeder <- mkBRAMFeeder(); |
PLBMaster plbMaster <- mkPLBMaster; |
|
Reg#(TesterState) state <- mkReg(Idle); |
Reg#(BlockAddr) baseRegLoad <- mkReg(0); |
Reg#(BlockAddr) baseRegStore <- mkReg(0); |
Reg#(Bit#(19)) commandCount <- mkReg(0); |
Reg#(Bit#(32)) commandsComplete <- mkReg(1); |
FIFO#(BusWord) dataFIFO <- mkSizedFIFO(32); |
Reg#(Bool) evenZero <- mkReg(True); |
|
rule grabInstruction(state == Idle); |
PPCMessage inst <- feeder.ppcMessageOutput.get; |
baseRegLoad <= truncate(pack(inst)); |
baseRegStore <= truncate(pack(inst)); |
state <= Running; |
endrule |
|
rule issueCommand(state == Running); |
commandCount <= commandCount + 1; |
if(commandCount + 1 == 0) |
begin |
state <= Idle; |
feeder.ppcMessageInput.put(pack(commandsComplete)); |
commandsComplete <= commandsComplete + 1; |
end |
|
if(commandCount[2] == 0) |
begin |
baseRegLoad <= baseRegLoad + fromInteger(valueof(TMul#(BeatsPerBurst,WordsPerBeat))); |
plbMaster.plbMasterCommandInput.put(tagged LoadPage (baseRegLoad)); |
end |
else |
begin |
baseRegStore <= baseRegStore + fromInteger(valueof(TMul#(BeatsPerBurst,WordsPerBeat))); |
plbMaster.plbMasterCommandInput.put(tagged StorePage (baseRegStore)); |
end |
endrule |
|
rule inputing; |
BusWord data <- plbMaster.wordOutput.get; |
dataFIFO.enq(data); |
endrule |
|
rule outputing; |
plbMaster.wordInput.put(unpack((~(pack(dataFIFO.first))) & (~1))); |
dataFIFO.deq; |
endrule |
|
interface plbMasterWires = plbMaster.plbMasterWires; |
interface bramInitiatorWires = feeder.bramInitiatorWires; |
|
endmodule |
/trunk/lib/bsv/FIFOUtiltity/FIFOUtility.bsv
0,0 → 1,13
import FIFO::*; |
import FIFOF::*; |
|
function FIFO#(fifo_type) guardedfifofToFifo( FIFOF#(fifo_type) fifo); |
|
FIFO#(fifo_type) f = interface FIFO#(fifo_type); |
method first = fifo.first; |
method enq = fifo.enq; |
method deq = fifo.deq; |
method clear = fifo.clear; |
endinterface; |
return f; |
endfunction |
/trunk/lib/bsv/BRAMFeeder/build/Makefile
0,0 → 1,32
srcdir = ../src |
debugdir = ../../Debug |
testdir = ../test |
commondir = ../../common |
bramdir = ../../BRAM/ |
bdir = build/bdir |
vdir = build/vdir |
cdir = build/cdir |
simdir = build/simdir |
|
BSC = bsc |
|
VER_OPTS = +RTS -K100000000 --RTS -u -v -verilog -aggressive-conditions -vdir $(vdir) -bdir $(bdir) |
SIM_OPTS = +RTS -K100000000 --RTS -u -v -sim -aggressive-conditions -show-schedule -vdir $(vdir) -bdir $(bdir) |
EXE_OPTS = +RTS -K100000000 --RTS -simdir $(simdir) -sim |
C_OPTS = -c -fPIC |
|
build: |
mkdir -p build |
mkdir -p $(bdir) |
mkdir -p $(vdir) |
mkdir -p $(cdir) |
mkdir -p $(simdir) |
|
BRAMFeeder: build |
$(BSC) $(VER_OPTS) -p +:$(testdir):$(srcdir):$(bdir):$(bramdir):$(debugdir) -g mkBRAMFeeder $(srcdir)/BRAMFeeder.bsv |
|
|
clean: |
rm -rf build |
|
.PHONY: build |
/trunk/lib/bsv/BRAMFeeder/src/BRAMFeeder.bsv
0,0 → 1,226
/* |
Copyright (c) 2007 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Michael Pellauer, Nirav Dave |
*/ |
|
import BRAM::*; |
import BRAMInitiatorWires::*; |
import GetPut::*; |
import FIFO::*; |
import FIFOF::*; |
//import Types::*; |
//import Interfaces::*; |
import Debug::*; |
|
import BRAMInitiator::*; |
|
//A message to the PPC |
typedef Bit#(32) PPCMessage; |
|
|
typedef enum{ |
FI_Initialize, |
FI_InIdle, |
FI_InStartCheckRead, |
FI_InStartRead, |
FI_InStartTake, |
FI_OutStartCheckWrite, |
FI_OutStartWrite, |
FI_OutStartPush, |
FI_CheckLoadStore, |
FI_Load, |
FI_LoadTake, |
FI_Store, |
FI_StorePush, |
FI_command |
} FeederState deriving(Eq,Bits); |
|
|
interface Feeder; |
|
interface Put#(PPCMessage) ppcMessageInput; |
interface Get#(PPCMessage) ppcMessageOutput; |
interface BRAMInitiatorWires#(Bit#(14)) bramInitiatorWires; |
|
endinterface |
|
Bool feederDebug = False; |
|
(* synthesize *) |
module mkBRAMFeeder(Feeder); |
|
// Data is held in 2 addr blocks. as |
// Addr n : 1---------22222 <- 1 valid bit (otherwise all zero) |
// 2 top bits of payload |
// n+1 : 333333333333333 <- 3 rest of payload |
|
//State |
|
BRAMInitiator#(Bit#(14)) bramInit <- mkBRAMInitiator; |
let bram = bramInit.bram; |
|
//BRAM#(Bit#(16), Bit#(32)) bram <- mkBRAM_Full(); |
|
FIFOF#(PPCMessage) ppcMesgQ <- mkFIFOF(); |
FIFOF#(PPCMessage) ppcInstQ <- mkFIFOF(); |
|
let minReadPtr = 0; |
let maxReadPtr = 31; |
let minWritePtr = 32; |
let maxWritePtr = 63; |
|
let ready = True; |
|
let debugF = debug(feederDebug); |
|
Reg#(Bit#(14)) readPtr <- mkReg(minReadPtr); |
|
Reg#(Bit#(14)) writePtr <- mkReg(minWritePtr); |
|
Reg#(FeederState) state <- mkReg(FI_InStartCheckRead); |
|
Reg#(Bit#(32)) partialRead <- mkReg(0); |
|
Reg#(Bit#(30)) heartbeat <- mkReg(0); |
|
//Every so often send a message to the PPC indicating we're still alive |
|
rule beat (True); |
|
let newheart = heartbeat + 1; |
|
heartbeat <= newheart; |
|
if (newheart == 0) |
ppcMesgQ.enq(0); |
|
endrule |
|
/////////////////////////////////////////////////////////// |
//Initialize |
/////////////////////////////////////////////////////////// |
|
//Reg#(Maybe#(Bit#(14))) initReg <- mkReg(Just(0)); |
|
//Bool ready = !isJust(initReg); |
|
//rule initBRAM(initReg matches tagged Just .i); |
// $display("Init"); |
// bram.write(i, 0); |
// initReg <= (i == maxWritePtr) ? Nothing : Just (i + 1); |
//endrule |
|
/////////////////////////////////////////////////////////// |
// In goes to FPGA, Out goes back to PPC |
/////////////////////////////////////////////////////////// |
|
let state_tryread = (ppcInstQ.notFull ? FI_InStartCheckRead: FI_InIdle); |
let state_trywrite = (ppcMesgQ.notEmpty) ? FI_OutStartCheckWrite : FI_InIdle; |
|
rule inStartIdle(ready && state == FI_InIdle); |
if(state_tryread == FI_InIdle) |
begin |
state <= state_trywrite; |
end |
else |
begin |
state <= state_tryread; |
end |
endrule |
|
|
rule inStartCheckRead(ready && state == FI_InStartCheckRead); |
debugF($display("BRAM: StartCheckRead")); |
bram.read_req(readPtr); |
state <= FI_InStartRead; |
endrule |
|
rule inStartRead(ready && state == FI_InStartRead); |
|
let v <- bram.read_resp(); |
Bool valid = (v[31] == 1); |
state <= (valid) ? FI_InStartTake : state_trywrite; |
|
debugF($display("BRAM: StartRead %h", v)); |
if (valid) |
begin |
//$display("BRAM: read fstinst [%d] = %h",readPtr, v); |
partialRead <= v; |
bram.read_req(readPtr+1); // |
end |
endrule |
|
rule inStartTake(ready && state == FI_InStartTake); |
debugF($display("BRAM: StartTake")); |
let val <- bram.read_resp(); |
|
Bit#(63) pack_i = truncate({partialRead,val}); |
|
PPCMessage i = unpack(truncate(pack_i));//truncate({partialRead,val})); |
|
ppcInstQ.enq(i); |
// $display("BRAM: read sndinst [%d] = %h",readPtr+1, val); |
// $display("BRAM: got PPCMessage %h",pack_i); |
// $display("Getting Inst: %h %h => %h",partialRead, val, {partialRead,val}); |
bram.write(readPtr, 0); |
readPtr <= (readPtr + 2 > maxReadPtr) ? minReadPtr : (readPtr + 2); |
state <= state_trywrite; |
endrule |
|
rule inStartCheckWrite(ready && state == FI_OutStartCheckWrite); |
debugF($display("BRAM: StartCheckWrite")); |
bram.read_req(writePtr); |
state <= FI_OutStartWrite; |
endrule |
|
rule inStartWrite(ready && state == FI_OutStartWrite); |
debugF($display("BRAM: StartWrite")); |
let v <- bram.read_resp(); |
Bool valid = (v[31] == 0); |
state <= (valid) ? FI_OutStartPush : state_tryread; |
if (valid) begin |
$display("BRAM: write [%d] = %h",writePtr+1, ppcMesgQ.first); |
bram.write(writePtr+1, ppcMesgQ.first()); |
ppcMesgQ.deq(); |
end |
endrule |
|
rule inStartPush(ready && state == FI_OutStartPush); |
debugF($display("BRAM: StartPush")); |
$display("BRAM: write [%d] = %h",writePtr, 32'hFFFFFFFF); |
bram.write(writePtr, 32'hFFFFFFFF);//all 1s |
writePtr <= (writePtr + 2 > maxWritePtr) ? minWritePtr : (writePtr + 2); |
state <= state_tryread; |
endrule |
|
//Interface |
|
interface ppcMessageInput = fifoToPut(fifofToFifo(ppcMesgQ)); |
interface ppcMessageOutput = fifoToGet(fifofToFifo(ppcInstQ)); |
|
interface bramInitiatorWires = bramInit.bramInitiatorWires; |
|
endmodule |
|
/trunk/lib/bsv/BRAMFeeder/src/BRAMInitiatorWires.bsv
0,0 → 1,50
/* |
Copyright (c) 2007 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Kermin Fleming |
*/ |
|
interface BRAMInitiatorWires#(type idx_type); |
(* always_ready, always_enabled, prefix="" *) |
method Bit#(1) bramCLK(); |
|
(* always_ready, always_enabled, prefix="" *) |
method Bit#(1) bramRST(); |
|
(* always_ready, always_enabled, prefix="" *) |
method idx_type bramAddr(); |
|
(* always_ready, always_enabled, prefix="" *) |
method Bit#(32) bramDout(); |
|
(* always_ready, always_enabled, prefix="" *) |
method Action bramDin(Bit#(32) din); |
|
(* always_ready, always_enabled, prefix="" *) |
method Bit#(4) bramWEN(); |
|
(* always_ready, always_enabled, prefix="" *) |
method Bit#(1) bramEN(); |
|
endinterface |
/trunk/lib/bsv/BRAMFeeder/src/BRAMInitiator.v
0,0 → 1,119
/* |
Copyright (c) 2007 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Kermin Fleming |
*/ |
|
module BRAMInitiator(CLK, RST_N, |
RD_ADDR, RD_RDY, RD_EN, |
DOUT, DOUT_RDY, DOUT_EN, |
WR_ADDR, WR_VAL, WR_EN, |
BRAM_Addr, BRAM_Dout, BRAM_Din,BRAM_Dummy_Enable, |
BRAM_WEN, BRAM_EN, BRAM_RST, |
BRAM_CLK); |
|
// synopsys template |
parameter addr_width = 1; |
|
input CLK; |
input RST_N; |
|
// Read Port |
// req |
input [addr_width -1 : 0] RD_ADDR; |
input RD_EN; |
output RD_RDY; |
// resp |
output [31 : 0] DOUT; |
output DOUT_RDY; |
input DOUT_EN; |
|
// Write Port |
// req |
input [addr_width - 1 : 0] WR_ADDR; |
input [31 : 0] WR_VAL; |
input WR_EN; |
|
// BRAM Wires |
output [addr_width - 1 : 0] BRAM_Addr; |
output [31 : 0] BRAM_Dout; |
input [31 : 0] BRAM_Din; |
input BRAM_Dummy_Enable; |
output [3 : 0] BRAM_WEN; |
output BRAM_EN; |
output BRAM_RST; |
output BRAM_CLK; |
|
|
// Assignments |
assign BRAM_CLK = CLK; |
assign BRAM_EN = RST_N; // disable the BRAM if we are in reset |
assign BRAM_RST = 1'b0; // Never reset the BRAM. |
assign BRAM_Addr = (WR_EN)?(WR_ADDR):(RD_ADDR); |
assign BRAM_WEN = {WR_EN,WR_EN,WR_EN,WR_EN}; |
assign BRAM_Dout = WR_VAL; |
|
reg RD_REQ_MADE; |
|
reg [1:0] CTR; |
|
/*always@(BRAM_Din) |
$display("BRAMInitiator.v BRAM_Din: %x",BRAM_Din); |
*/ |
|
FIFO2#(.width(32)) q(.RST_N(RST_N), |
.CLK(CLK), |
.D_IN(BRAM_Din), |
.ENQ(RD_REQ_MADE), |
.DEQ(DOUT_EN), |
.CLR(1'b0), |
.D_OUT(DOUT), |
.FULL_N(), |
.EMPTY_N(DOUT_RDY)); |
|
assign RD_RDY = (CTR > 0); |
|
always@(posedge CLK) |
begin |
if (!RST_N) |
begin |
CTR <= 2; |
end |
else |
begin |
/*if(RD_EN) |
$display("BRAMInitiator: RD_EN"); |
if(WR_EN) |
$display("BRAMInitiator: WR_EN"); |
*/ |
|
RD_REQ_MADE <= RD_EN; |
|
CTR <= (RD_EN) ? |
(DOUT_EN) ? CTR : CTR - 1 : |
(DOUT_EN) ? CTR + 1 : CTR; |
end |
end // always@ (posedge CLK) |
|
endmodule |
/trunk/lib/bsv/BRAMFeeder/src/mkBRAMFeeder.sched
0,0 → 1,169
=== Generated schedule for mkBRAMFeeder === |
|
Method schedule |
--------------- |
Method: ppcMessageInput_put |
Ready signal: ppcMesgQ.i_notFull && ppcMesgQ.notFull |
Conflict-free: bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
Sequenced before (restricted): ppcMessageOutput_get |
Conflicts: ppcMessageInput_put |
|
Method: ppcMessageOutput_get |
Ready signal: ppcInstQ.notEmpty && ppcInstQ.i_notEmpty |
Conflict-free: bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
Sequenced after (restricted): ppcMessageInput_put |
Conflicts: ppcMessageOutput_get |
|
Method: bramInitiatorWires_bramCLK |
Ready signal: True |
Conflict-free: ppcMessageInput_put, |
ppcMessageOutput_get, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
|
Method: bramInitiatorWires_bramRST |
Ready signal: True |
Conflict-free: ppcMessageInput_put, |
ppcMessageOutput_get, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
|
Method: bramInitiatorWires_bramAddr |
Ready signal: True |
Conflict-free: ppcMessageInput_put, |
ppcMessageOutput_get, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
|
Method: bramInitiatorWires_bramDout |
Ready signal: True |
Conflict-free: ppcMessageInput_put, |
ppcMessageOutput_get, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
|
Method: bramInitiatorWires_bramDin |
Ready signal: True |
Conflict-free: ppcMessageInput_put, |
ppcMessageOutput_get, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
|
Method: bramInitiatorWires_bramWEN |
Ready signal: True |
Conflict-free: ppcMessageInput_put, |
ppcMessageOutput_get, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
|
Method: bramInitiatorWires_bramEN |
Ready signal: True |
Conflict-free: ppcMessageInput_put, |
ppcMessageOutput_get, |
bramInitiatorWires_bramCLK, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramEN |
|
Rule schedule |
------------- |
Rule: inStartPush |
Predicate: state == 4'd7 |
Blocking rules: (none) |
|
Rule: inStartWrite |
Predicate: bramInit_bramFlat.RDY_read_resp && ppcMesgQ.i_notEmpty && |
(state == 4'd6) |
Blocking rules: ppcMessageInput_put |
|
Rule: inStartCheckWrite |
Predicate: bramInit_bramFlat.RDY_read_req && (state == 4'd5) |
Blocking rules: (none) |
|
Rule: inStartTake |
Predicate: bramInit_bramFlat.RDY_read_resp && ppcInstQ.i_notFull && |
(state == 4'd4) |
Blocking rules: ppcMessageInput_put |
|
Rule: inStartRead |
Predicate: bramInit_bramFlat.RDY_read_resp && |
bramInit_bramFlat.RDY_read_req && |
(state == 4'd3) |
Blocking rules: (none) |
|
Rule: inStartCheckRead |
Predicate: bramInit_bramFlat.RDY_read_req && (state == 4'd2) |
Blocking rules: (none) |
|
Rule: inStartIdle |
Predicate: state == 4'd1 |
Blocking rules: (none) |
|
Rule: beat |
Predicate: (! (heartbeat == 30'd1073741823)) || ppcMesgQ.i_notFull |
Blocking rules: ppcMessageInput_put |
|
Logical execution order: bramInitiatorWires_bramEN, |
bramInitiatorWires_bramWEN, |
bramInitiatorWires_bramDin, |
bramInitiatorWires_bramDout, |
bramInitiatorWires_bramAddr, |
bramInitiatorWires_bramRST, |
bramInitiatorWires_bramCLK, |
inStartRead, |
inStartIdle, |
ppcMessageInput_put, |
inStartPush, |
inStartWrite, |
ppcMessageOutput_get, |
inStartCheckWrite, |
inStartTake, |
inStartCheckRead, |
beat |
|
============================================ |
/trunk/lib/bsv/BRAMFeeder/src/BRAMInitiator.bsv
0,0 → 1,116
/* |
Copyright (c) 2007 MIT |
|
Permission is hereby granted, free of charge, to any person |
obtaining a copy of this software and associated documentation |
files (the "Software"), to deal in the Software without |
restriction, including without limitation the rights to use, |
copy, modify, merge, publish, distribute, sublicense, and/or sell |
copies of the Software, and to permit persons to whom the |
Software is furnished to do so, subject to the following |
conditions: |
|
The above copyright notice and this permission notice shall be |
included in all copies or substantial portions of the Software. |
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
OTHER DEALINGS IN THE SOFTWARE. |
|
Author: Kermin Fleming |
*/ |
|
import BRAMInitiatorWires::*; |
import BRAM::*; |
|
interface BRAMInitiator#(type idx_type); |
interface BRAM#(idx_type, Bit#(32)) bram; |
interface BRAMInitiatorWires#(idx_type) bramInitiatorWires; |
endinterface |
|
interface BRAMInitiatorFlat#(type idx_type); |
method ActionValue#(Bit#(32)) read_resp(); |
method Action read_req(idx_type idx); |
method Action write(idx_type idx, Bit#(32) value); |
method Bit#(1) bramCLK(); |
method Bit#(1) bramRST(); |
method idx_type bramAddr(); |
method Bit#(32) bramDout(); |
method Action bramDin(Bit#(32) value); |
method Bit#(4) bramWEN(); |
method Bit#(1) bramEN(); |
endinterface |
|
|
module mkBRAMInitiator (BRAMInitiator#(idx_type)) |
provisos |
(Bits#(idx_type, idx), |
Literal#(idx_type)); |
BRAMInitiatorFlat#(idx_type) bramFlat <- mkBRAMInitiatorFlat(); |
|
interface BRAM bram; |
method write = bramFlat.write; |
method read_req = bramFlat.read_req; |
method read_resp = bramFlat.read_resp; |
endinterface |
|
interface BRAMInitiatorWires bramInitiatorWires; |
method bramCLK = bramFlat.bramCLK; |
method bramRST = bramFlat.bramRST; |
method bramAddr = bramFlat.bramAddr; |
method bramDout = bramFlat.bramDout; |
method bramDin = bramFlat.bramDin; |
method bramWEN = bramFlat.bramWEN; |
method bramEN = bramFlat.bramEN; |
endinterface |
|
endmodule |
|
|
|
import "BVI" BRAMInitiator = module mkBRAMInitiatorFlat |
//interface: |
(BRAMInitiatorFlat#(idx_type)) |
provisos |
(Bits#(idx_type, idx), |
Literal#(idx_type)); |
|
default_clock clk(CLK); |
|
parameter addr_width = valueof(idx); |
|
method DOUT read_resp() ready(DOUT_RDY) enable(DOUT_EN); |
|
method read_req(RD_ADDR) ready(RD_RDY) enable(RD_EN); |
method write(WR_ADDR, WR_VAL) enable(WR_EN); |
|
method BRAM_CLK bramCLK(); |
method BRAM_RST bramRST(); |
method BRAM_Addr bramAddr(); |
method BRAM_Dout bramDout(); |
method bramDin(BRAM_Din) enable(BRAM_Dummy_Enable); |
method BRAM_WEN bramWEN(); |
method BRAM_EN bramEN(); |
|
schedule read_req CF (read_resp, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule read_resp CF (read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule write CF (read_req, read_resp, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
// All the BRAM methods are CF |
schedule bramCLK CF (read_resp, read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule bramRST CF (read_resp, read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule bramAddr CF (read_resp, read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule bramDout CF (read_resp, read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule bramDin CF (read_resp, read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule bramWEN CF (read_resp, read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
schedule bramEN CF (read_resp, read_req, write, bramCLK, bramRST, bramAddr, bramDout, bramDin, bramWEN, bramEN); |
|
schedule read_req C read_req; |
schedule read_resp C read_resp; |
schedule write C write; |
|
endmodule |