mirror of
https://github.com/aolofsson/oh.git
synced 2025-02-07 06:44:09 +08:00
Merge branch 'master' of github.com:aolofsson/private-oh into pr_aolofsson
This commit is contained in:
commit
65a13b5067
@ -193,6 +193,8 @@ TBD
|
|||||||
* [GTKWave](http://gtkwave.sourceforge.net)
|
* [GTKWave](http://gtkwave.sourceforge.net)
|
||||||
* [Wavedrom](http://wavedrom.com/editor.html)
|
* [Wavedrom](http://wavedrom.com/editor.html)
|
||||||
* [FuseSoC](https://github.com/olofk/fusesoc)
|
* [FuseSoC](https://github.com/olofk/fusesoc)
|
||||||
|
* [OpenROAD](https://github.com/The-OpenROAD-Project/OpenROAD)
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
The OH! repository source code is licensed under the MIT license unless otherwise specified. See [LICENSE](LICENSE) for MIT copyright terms. Design specific licenses can be found in the folder root (eg: aes/LICENSE)
|
The OH! repository source code is licensed under the MIT license unless otherwise specified. See [LICENSE](LICENSE) for MIT copyright terms. Design specific licenses can be found in the folder root (eg: aes/LICENSE)
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
LIST OF OPEN SOURCE PRINTED CIRCUIT BOARDS
|
|
||||||
======================================================
|
|
||||||
|
|
||||||
>> Open source means that the original source code and design files are provided under a copyleft or permissive open source license.
|
|
||||||
|
|
||||||
1. [List of Single Board Computers (SBCs)](#single-board-computers)
|
|
||||||
2. [List of RF Boards](#rf-boards)
|
|
||||||
3. [List of Camera Boards](#camera-boards)
|
|
||||||
4. [List of Other Boards](#other-boards)
|
|
||||||
5. [How to Add a Board](#how-to-add-a-board)
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Single Board Computers
|
|
||||||
|
|
||||||
| Name | Type | Tool | Author | Description |
|
|
||||||
|-------------------------------------------|--------|---------| -----------------| ---------------------------------------|
|
|
||||||
| [Arduino Uno](./arduino-uno.md) | SBC | SBC | Arduino | Arduino |
|
|
||||||
| [Beaglebone Black](./beaglebone-black.md) | SBC | Allegro | CircuitCo | TI processor SBC |
|
|
||||||
| [Olinuxino](./olinuxino.md) | SBC | KiCad | Olimex | Industrial grade SBC |
|
|
||||||
| [Parallella](./parallella.md) | SBC | Allegro | Adapteva | SBC with Zynq FPGA + Epiphany |
|
|
||||||
| [Rascal Micro](./rascal-micro.md) | SBC | Altium | Brandon Stafford | SBC that works with Arduino shields |
|
|
||||||
|
|
||||||
# RF Boards
|
|
||||||
|
|
||||||
| Name | Type | Tool | Author | Description |
|
|
||||||
|----------------------------------------|--------|---------| --------------------| ---------------------------------------------|
|
|
||||||
| [Hack RF](./hackrf.md) | RF | KiCad | Great Scott Gadgets | 1MHz-6GHz Half Duplex RF board |
|
|
||||||
| [Parallella Lime](./parallella-lime.md)| RF | KiCad | Lime Micro | Parallella 300MHz-3.8GHz Parallella SDR board |
|
|
||||||
|
|
||||||
# Camera Boards
|
|
||||||
| Name | Type | Tool | Author | Description |
|
|
||||||
|---------------------------------------|--------|---------| -----------| ------------------------------------------------|
|
|
||||||
| [KVision](./kvision.md) | Camera | Altium | Emil Fresk | Parallella Stero camera board |
|
|
||||||
|
|
||||||
# Other Boards
|
|
||||||
| Name | Type | Tool | Author | Description |
|
|
||||||
|-----------------------------------------|--------|---------|------------|-------------------------------------------------|
|
|
||||||
| [AAFM ](./aafm.md) | FMC | Allegro | BittWare | FMC board with 4 Epiphany-III chips |
|
|
||||||
| [OpenLog](./openlog.md) | Adapter| Eagle | SparkFun | Data logger |
|
|
||||||
| [MicroSD Adapter](./microsd-adapter.md) | Adapter| Eagle | Adafruit | MicroSD to SD card adapter for RPI |
|
|
||||||
| [Porcupine](./porcupine.md) | Adapter| KiCad | Adapteva | Parallella breakout board |
|
|
||||||
|
|
||||||
# How to Add a Board
|
|
||||||
1. Fork this repository to your personal github account using the 'fork' button above
|
|
||||||
2. Clone your "OH" fork to a local computer using 'git clone'
|
|
||||||
3. Create a file "your_board".md in the "boards" directory
|
|
||||||
4. Update the table in this README.md file with a link to that new description
|
|
||||||
5. Use git add-->git commit-->git push to add changes to your fork of 'parallella-examples'
|
|
||||||
6. Submit a pull request by clicking the 'pull request' button on YOUR github 'OH' repo
|
|
||||||
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
## AAFM
|
|
||||||
* Description: FMC board with 4 Epiphany-III chips
|
|
||||||
* Type: FMC
|
|
||||||
* CAD Tool: Allegro/Orcad
|
|
||||||
* Author: BittWare
|
|
||||||
* License: Creative Commons Attribution-Share Alike 3.0 Unprotected License
|
|
||||||
* [Schematic](https://github.com/parallella/parallella-hw/tree/master/aafm)
|
|
||||||
* [Layout](https://github.com/parallella/parallella-hw/tree/master/aafm)
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
## Arduino Uno
|
|
||||||
* Description: Arduino Computer
|
|
||||||
* Type: SBC
|
|
||||||
* CAD Tool: Eagle
|
|
||||||
* Author: Arduino
|
|
||||||
* License: Creative Commons
|
|
||||||
* [Schematic](https://www.arduino.cc/en/uploads/Main/arduino_Uno_Rev3-02-TH.zip)
|
|
||||||
* [Layout](https://www.arduino.cc/en/uploads/Main/arduino_Uno_Rev3-02-TH.zip)
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
## Beaglebone Black
|
|
||||||
* Description: Credit card sized single board computer
|
|
||||||
* Type: SBC
|
|
||||||
* CAD Tool: Allegro/Orcad
|
|
||||||
* Author: CircuitCo
|
|
||||||
* [Schematic](https://github.com/CircuitCo/BeagleBone-Black)
|
|
||||||
* [Layout](https://github.com/CircuitCo/BeagleBone-Black)
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
## Hack RF
|
|
||||||
* Description: Credit card sized single board computer
|
|
||||||
* Type: SBC
|
|
||||||
* CAD Tool: KiCad
|
|
||||||
* Author: Great Scott Gadgets
|
|
||||||
* [Schematic](https://github.com/mossmann/hackrf/tree/master/doc/hardware)
|
|
||||||
* [Layout](https://github.com/mossmann/hackrf/tree/master/doc/hardware)
|
|
||||||
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
## KVison
|
|
||||||
* Description: Stereo camera board for parallella
|
|
||||||
* Type: Adapter
|
|
||||||
* CAD Tool: Altium
|
|
||||||
* Author: Emil Fresk
|
|
||||||
* License: Creative Commons Attribution-Share Alike 3.0 Unprotected License
|
|
||||||
* [Schematic](https://github.com/parallella/parallella-hw/tree/master/kvision)
|
|
||||||
* [Layout](https://github.com/parallella/parallella-hw/tree/master/kvision)
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
|
|
||||||
## MicroSD Adapter
|
|
||||||
* Description: MicroSD to SD card adapter for RPI
|
|
||||||
* Type: Adapter
|
|
||||||
* CAD Tool: eagle
|
|
||||||
* Author: Adafruit
|
|
||||||
* License: Creative Commons Attribution, Share-Alike license
|
|
||||||
* [Schematic](https://github.com/adafruit/Adafruit-Low-profile-microSD-to-SD-Adapter-PCB)
|
|
||||||
* [Layout](https://github.com/adafruit/Adafruit-Low-profile-microSD-to-SD-Adapter-PCB)
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
## Olinuxino
|
|
||||||
* Description: AM3352 (TI) based single board computer
|
|
||||||
* Type: Single Board Computer
|
|
||||||
* Tool: KiCad
|
|
||||||
* Author: Olimex
|
|
||||||
* License: Creative Commons Attribution-Share Alike 3.0 United States License
|
|
||||||
* [Schematic](https://github.com/OLIMEX/OLINUXINO/tree/master/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_B)
|
|
||||||
* [Layout](https://github.com/OLIMEX/OLINUXINO/tree/master/HARDWARE/A64-OLinuXino/A64-OLinuXino_Rev_B)
|
|
||||||
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
## OpenLog
|
|
||||||
* Type: Other
|
|
||||||
* Tool: Eagle
|
|
||||||
* Author: SparkFun
|
|
||||||
* Description: Data logger
|
|
||||||
* License: Creative Commons Attribution-Share Alike 3.0 United States License
|
|
||||||
* [Schematic](https://github.com/sparkfun/OpenLog)
|
|
||||||
* [Layout](https://github.com/sparkfun/OpenLog)
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
## Parallella Lime
|
|
||||||
* Description: 300MHz-3.8GHz Parallella SDR board
|
|
||||||
* Type: RF
|
|
||||||
* Tool: KiCad
|
|
||||||
* Author: Lime Micro
|
|
||||||
* License: Creative Commons Attribution 3.0 Unported licence
|
|
||||||
* [Schematic](https://github.com/parallella/parallella-hw/tree/master/parallella-lime)
|
|
||||||
* [Layout](https://github.com/parallella/parallella-hw/tree/master/parallella-lime)
|
|
||||||
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
|||||||
## Parallella
|
|
||||||
* Description: Credit card sized computer with Zynq FPGA and 16-core Epiphany coprocessor
|
|
||||||
* Type: SBC
|
|
||||||
* Tool: Allegro
|
|
||||||
* Author: Adapteva
|
|
||||||
* License: Creative Commons Attribution 3.0 Unported licence
|
|
||||||
* Docs: [http://parallella.org/docs/parallella_manual.pdf](http://parallella.org/docs/parallella_manual.pdf)
|
|
||||||
* Schematic: [https://github.com/parallella/parallella-hw/tree/master/parallella](https://github.com/parallella/parallella-hw/tree/master/parallella)
|
|
||||||
* Layout: [https://github.com/parallella/parallella-hw/tree/master/parallella](https://github.com/parallella/parallella-hw/tree/master/parallella)
|
|
||||||
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
## Porcupine
|
|
||||||
* Description: Parallella breakout board
|
|
||||||
* Type: Adapter
|
|
||||||
* Tool: KiCad
|
|
||||||
* Author: Adapteva
|
|
||||||
* License: Creative Commons Attribution 3.0 Unported licence
|
|
||||||
* [Schematic](https://github.com/parallella/parallella-hw/tree/master/porcupine)
|
|
||||||
* [Layout](https://github.com/parallella/parallella-hw/tree/master/porcupine)
|
|
||||||
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
|||||||
|
|
||||||
## Rascal Micro
|
|
||||||
* Description: Small, open source computer that works with Arduino shields
|
|
||||||
* Type: SBC
|
|
||||||
* Tool: Altium
|
|
||||||
* Author: Brandon Stafford
|
|
||||||
* License: Creative Commons Attribution 3.0 Unported licence
|
|
||||||
* [Schematic](http://rascalmicro.com/files/rascal-1.2.schdoc)
|
|
||||||
* [Layout](http://rascalmicro.com/files/rascal-1.2.pcbdoc)
|
|
60
common/dv/dv_stimulus.v
Normal file
60
common/dv/dv_stimulus.v
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
module dv_top ();
|
||||||
|
parameter DW = 64; // Memory width
|
||||||
|
parameter MAW = 15; // Memory address width
|
||||||
|
|
||||||
|
//regs/wires
|
||||||
|
reg [1023:0] filename;
|
||||||
|
wire [DW-1:0] ext_packet;
|
||||||
|
|
||||||
|
/*AUTOWIRE*/
|
||||||
|
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
||||||
|
wire nreset; // From dv_ctrl of dv_ctrl.v
|
||||||
|
wire start; // From dv_ctrl of dv_ctrl.v
|
||||||
|
wire stim_access; // From stimulus of stimulus.v
|
||||||
|
wire stim_done; // From stimulus of stimulus.v
|
||||||
|
wire [DW-1:0] stim_packet; // From stimulus of stimulus.v
|
||||||
|
wire vdd; // From dv_ctrl of dv_ctrl.v
|
||||||
|
wire vss; // From dv_ctrl of dv_ctrl.v
|
||||||
|
// End of automatics
|
||||||
|
|
||||||
|
assign test_done = 1'b1;
|
||||||
|
assign dut_active = 1'b1;
|
||||||
|
//Reset and clocks
|
||||||
|
dv_ctrl dv_ctrl(.clk1 (ext_clk),
|
||||||
|
.clk2 (dut_clk),
|
||||||
|
/*AUTOINST*/
|
||||||
|
// Outputs
|
||||||
|
.nreset (nreset),
|
||||||
|
.start (start),
|
||||||
|
.vdd (vdd),
|
||||||
|
.vss (vss),
|
||||||
|
// Inputs
|
||||||
|
.dut_active (dut_active),
|
||||||
|
.stim_done (stim_done),
|
||||||
|
.test_done (test_done));
|
||||||
|
|
||||||
|
//Stimulus
|
||||||
|
assign ext_start = start;
|
||||||
|
assign ext_access = 'b0;
|
||||||
|
assign ext_packet = 'b0;
|
||||||
|
assign dut_wait = 'b0;
|
||||||
|
|
||||||
|
|
||||||
|
stimulus #(.DW(DW),.MAW(MAW),.HEXFILE("firmware.hex"))
|
||||||
|
stimulus(
|
||||||
|
/*AUTOINST*/
|
||||||
|
// Outputs
|
||||||
|
.stim_access (stim_access),
|
||||||
|
.stim_packet (stim_packet[DW-1:0]),
|
||||||
|
.stim_done (stim_done),
|
||||||
|
// Inputs
|
||||||
|
.nreset (nreset),
|
||||||
|
.ext_start (ext_start),
|
||||||
|
.ext_clk (ext_clk),
|
||||||
|
.ext_access (ext_access),
|
||||||
|
.ext_packet (ext_packet[DW-1:0]),
|
||||||
|
.dut_clk (dut_clk),
|
||||||
|
.dut_wait (dut_wait));
|
||||||
|
|
||||||
|
|
||||||
|
endmodule // unmatched end(function|task|module|primitive|interface|package|class|clocking)
|
3
common/dv/firmware_example.hex
Normal file
3
common/dv/firmware_example.hex
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
7766554433221101 //first line
|
||||||
|
FFEEDDCCBBEE9901 //second line
|
||||||
|
0000000000000000 //end of stimulus [0]=0
|
@ -1,4 +1,5 @@
|
|||||||
-y .
|
|
||||||
|
|
||||||
-y ../../common/dv
|
-y ../../common/dv
|
||||||
-y ../../emesh/dv
|
-y ../../emesh/dv
|
||||||
-y ../../memory/dv
|
-y ../../memory/dv
|
||||||
@ -29,3 +30,4 @@
|
|||||||
+incdir+../../gpio/hdl
|
+incdir+../../gpio/hdl
|
||||||
+incdir+../../spi/hdl
|
+incdir+../../spi/hdl
|
||||||
+incdir+../../mio/hdl
|
+incdir+../../mio/hdl
|
||||||
|
|
26
common/dv/oh_simchecker.v
Normal file
26
common/dv/oh_simchecker.v
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
module oh_simchecker #(parameter DW = 32 // Datapath width
|
||||||
|
)
|
||||||
|
(
|
||||||
|
//Inputs
|
||||||
|
input clk,
|
||||||
|
input nreset,
|
||||||
|
input [DW-1:0] result, // result to check
|
||||||
|
input [DW-1:0] reference, // reference result
|
||||||
|
output reg diff //fail indicator
|
||||||
|
);
|
||||||
|
|
||||||
|
always @ (negedge clk or negedge nreset)
|
||||||
|
if(~nreset)
|
||||||
|
diff <= 1'b0;
|
||||||
|
else if(result!==reference)
|
||||||
|
begin
|
||||||
|
diff <= 1'b1;
|
||||||
|
`ifdef CFG_SIM
|
||||||
|
$display("ERROR(%0t): result= %d(%h) reference= %d(%h)", $time, result,result, reference, reference);
|
||||||
|
`endif
|
||||||
|
end
|
||||||
|
else
|
||||||
|
diff <= 1'b0;
|
||||||
|
|
||||||
|
endmodule // oh_simchecker
|
||||||
|
|
148
common/dv/oh_simctrl.v
Normal file
148
common/dv/oh_simctrl.v
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/* verilator lint_off STMTDLY */
|
||||||
|
module oh_simctrl #( parameter CFG_CLK1_PERIOD = 10,
|
||||||
|
parameter CFG_CLK2_PERIOD = 20,
|
||||||
|
parameter CFG_TIMEOUT = 500
|
||||||
|
)
|
||||||
|
(
|
||||||
|
//control signals to drive
|
||||||
|
output nreset, // async active low reset
|
||||||
|
output clk1, // main clock
|
||||||
|
output clk2, // secondary clock
|
||||||
|
output start, // start test (level)
|
||||||
|
output vdd, // driving vdd
|
||||||
|
output vss, // driving vss
|
||||||
|
//input from testbench
|
||||||
|
input dut_active, // dut reset sequence is done
|
||||||
|
input stim_done, // stimulus is done
|
||||||
|
input test_done, // test is done
|
||||||
|
input test_diff // diff between dut and reference
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
localparam CFG_CLK1_PHASE = CFG_CLK1_PERIOD/2;
|
||||||
|
localparam CFG_CLK2_PHASE = CFG_CLK2_PERIOD/2;
|
||||||
|
|
||||||
|
//signal declarations
|
||||||
|
reg vdd;
|
||||||
|
reg vss;
|
||||||
|
reg nreset;
|
||||||
|
reg start;
|
||||||
|
reg clk1=0;
|
||||||
|
reg clk2=0;
|
||||||
|
reg [6:0] clk1_phase;
|
||||||
|
reg [6:0] clk2_phase;
|
||||||
|
reg test_fail;
|
||||||
|
integer seed,r;
|
||||||
|
reg [1023:0] testname;
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
// CONFIGURATION
|
||||||
|
//#################################
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
r=$value$plusargs("TESTNAME=%s", testname[1023:0]);
|
||||||
|
$timeformat(-9, 0, " ns", 20);
|
||||||
|
end
|
||||||
|
|
||||||
|
`ifndef VERILATOR
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
$dumpfile("waveform.vcd");
|
||||||
|
$dumpvars(0, testbench);
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
// RANDOM NUMBER GENERATOR
|
||||||
|
// (SEED SUPPLIED EXERNALLY)
|
||||||
|
//#################################
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
r=$value$plusargs("SEED=%s", seed);
|
||||||
|
//$display("SEED=%d", seed);
|
||||||
|
`ifdef CFG_RANDOM
|
||||||
|
clk1_phase = 1 + {$random(seed)}; //generate random values
|
||||||
|
clk2_phase = 1 + {$random(seed)}; //generate random values
|
||||||
|
`else
|
||||||
|
clk1_phase = CFG_CLK1_PHASE;
|
||||||
|
clk2_phase = CFG_CLK2_PHASE;
|
||||||
|
`endif
|
||||||
|
//$display("clk1_phase=%d clk2_phase=%d", clk1_phase,clk2_phase);
|
||||||
|
end
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
//CLK GENERATORS
|
||||||
|
//#################################
|
||||||
|
|
||||||
|
always
|
||||||
|
#(clk1_phase) clk1 = ~clk1;
|
||||||
|
|
||||||
|
always
|
||||||
|
#(clk2_phase) clk2 = ~clk2;
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
//ASYNC
|
||||||
|
//#################################
|
||||||
|
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
#(1)
|
||||||
|
nreset = 'b0;
|
||||||
|
vdd = 'b0;
|
||||||
|
vss = 'b0;
|
||||||
|
#(clk1_phase * 10 + 10) //ramping voltage
|
||||||
|
vdd = 'bx;
|
||||||
|
#(clk1_phase * 10 + 10) //voltage is safe
|
||||||
|
vdd = 'b1;
|
||||||
|
#(clk1_phase * 40 + 10) //hold reset for 20 clk cycles
|
||||||
|
nreset = 'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
//SYNCHRONOUS STIMULUS
|
||||||
|
//#################################
|
||||||
|
|
||||||
|
//START TEST
|
||||||
|
always @ (posedge clk1 or negedge nreset)
|
||||||
|
if(!nreset)
|
||||||
|
start <= 1'b0;
|
||||||
|
else if(dut_active & ~start)
|
||||||
|
begin
|
||||||
|
$display("-------------------");
|
||||||
|
$display("TEST %0s STARTED", testname);
|
||||||
|
start <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
//STOP SIMULATION ON END
|
||||||
|
always @ (posedge clk1 or negedge nreset)
|
||||||
|
if(!nreset)
|
||||||
|
test_fail <= 1'b0;
|
||||||
|
else if(stim_done & test_done)
|
||||||
|
begin
|
||||||
|
#500
|
||||||
|
$display("-------------------");
|
||||||
|
if(test_fail | test_diff)
|
||||||
|
$display("TEST %0s FAILED", testname);
|
||||||
|
else
|
||||||
|
$display("TEST %0s PASSED", testname);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
else if (test_diff)
|
||||||
|
test_fail <= 1'b1;
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
// TIMEOUT
|
||||||
|
//#################################
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
#(CFG_TIMEOUT)
|
||||||
|
$display("TEST %0s FAILED ON TIMEOUT",testname);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule // oh_simctrl
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
143
common/dv/stimulus.v
Normal file
143
common/dv/stimulus.v
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
// A stimulus file provides inputs signals to the design under test (DUT).
|
||||||
|
// This stimulus module is designed to be compatible with verilog simulators,
|
||||||
|
// emulators, and FPGA prototyping. This is akin to a simple test vector generator
|
||||||
|
// No looping supported!
|
||||||
|
//
|
||||||
|
// Memory format:
|
||||||
|
// b0 = valid,
|
||||||
|
// b1-7 = wait time
|
||||||
|
// b8-bxxx = packet
|
||||||
|
//
|
||||||
|
// Test Process:
|
||||||
|
// 1. Zero out memory (or write program)
|
||||||
|
// 2. Set go signal
|
||||||
|
//
|
||||||
|
module stimulus #( parameter DW = 32, // Memory width=DW+
|
||||||
|
parameter MAW = 15, // Memory address width
|
||||||
|
parameter HEXFILE = "NONE" // Name of hex file
|
||||||
|
)
|
||||||
|
(
|
||||||
|
//Asynchronous Stimulus Reset
|
||||||
|
input nreset,
|
||||||
|
input ext_start, // Start driving stimulus
|
||||||
|
input use_timestamps,//b1-7 used for timestamps
|
||||||
|
input ignore_valid,//b0 valid bit ignored
|
||||||
|
//External Load port
|
||||||
|
input ext_clk,// External clock for write path
|
||||||
|
input ext_access, // Valid packet for memory
|
||||||
|
input [DW-1:0] ext_packet, // Packet for memory
|
||||||
|
//DUT Drive port
|
||||||
|
input dut_clk, // DUT side clock
|
||||||
|
input dut_wait, // DUT stall signal
|
||||||
|
output stim_access, // Access signal
|
||||||
|
output [DW-1:0] stim_packet, // Packet
|
||||||
|
output stim_done // Stimulus program done
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam MD = 1<<MAW; // Memory depth
|
||||||
|
|
||||||
|
//Registers
|
||||||
|
reg [DW-1:0] ram[0:MD-1];
|
||||||
|
reg [1:0] rd_state;
|
||||||
|
reg [MAW-1:0] wr_addr;
|
||||||
|
reg [MAW-1:0] rd_addr;
|
||||||
|
reg [255:0] memhfile;
|
||||||
|
reg [1:0] sync_pipe;
|
||||||
|
reg [6:0] rd_delay;
|
||||||
|
reg [DW-1:0] stim_packet;
|
||||||
|
reg stim_read;
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
// Init memory if configured
|
||||||
|
//#################################
|
||||||
|
generate
|
||||||
|
if(!(HEXFILE=="NONE"))
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
$display("Initializing STIMULUS from %s", HEXFILE);
|
||||||
|
$readmemh(HEXFILE, ram);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
// Write port state machine
|
||||||
|
//#################################
|
||||||
|
|
||||||
|
always @ (posedge ext_clk or negedge nreset)
|
||||||
|
if(!nreset)
|
||||||
|
wr_addr[MAW-1:0] <= 'b0;
|
||||||
|
else if(ext_access)
|
||||||
|
wr_addr[MAW-1:0] <= wr_addr[MAW-1:0] + 1;
|
||||||
|
|
||||||
|
//Synchronize ext_start to dut_clk domain
|
||||||
|
always @ (posedge dut_clk or negedge nreset)
|
||||||
|
if(!nreset)
|
||||||
|
sync_pipe[1:0] <= 1'b0;
|
||||||
|
else
|
||||||
|
sync_pipe[1:0] <= {sync_pipe[0],ext_start};
|
||||||
|
assign dut_start = sync_pipe[1];
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
// Read port state machine
|
||||||
|
//#################################
|
||||||
|
//1. Start on dut_start
|
||||||
|
//2. After thar update rd state machine on all not stall and not wait
|
||||||
|
//3. Set end state on special end packet
|
||||||
|
|
||||||
|
`define STIM_IDLE 2'b00
|
||||||
|
`define STIM_ACTIVE 2'b01
|
||||||
|
`define STIM_PAUSE 2'b10
|
||||||
|
`define STIM_DONE 2'b11
|
||||||
|
|
||||||
|
always @ (posedge dut_clk or negedge nreset)
|
||||||
|
if(!nreset)
|
||||||
|
begin
|
||||||
|
rd_state[1:0] <= `STIM_IDLE;
|
||||||
|
rd_addr[MAW-1:0] <= 'b0;
|
||||||
|
rd_delay[6:0] <= 'b0;
|
||||||
|
end
|
||||||
|
else if(~dut_wait)
|
||||||
|
case (rd_state[1:0])
|
||||||
|
`STIM_IDLE :
|
||||||
|
rd_state[1:0] <= dut_start ? `STIM_ACTIVE : `STIM_IDLE;
|
||||||
|
`STIM_ACTIVE :
|
||||||
|
begin
|
||||||
|
rd_state[1:0] <= (|rd_delay[6:0]) ? `STIM_PAUSE :
|
||||||
|
~stim_valid ? `STIM_DONE :
|
||||||
|
`STIM_ACTIVE;
|
||||||
|
rd_addr[MAW-1:0] <= rd_addr[MAW-1:0] + 1'b1;
|
||||||
|
rd_delay[6:0] <= {(7){use_timestamps}} & stim_packet[7:1];
|
||||||
|
end
|
||||||
|
`STIM_PAUSE :
|
||||||
|
begin
|
||||||
|
rd_state[1:0] <= (|rd_delay[6:0]) ? `STIM_PAUSE : `STIM_ACTIVE;
|
||||||
|
rd_delay[6:0] <= rd_delay[6:0] - 1'b1;
|
||||||
|
end
|
||||||
|
endcase // case (rd_state[1:0])
|
||||||
|
|
||||||
|
//Output Driver
|
||||||
|
assign stim_done = (rd_state[1:0] == `STIM_DONE);
|
||||||
|
assign stim_valid = ignore_valid | stim_packet[0];
|
||||||
|
|
||||||
|
//#################################
|
||||||
|
// RAM
|
||||||
|
//#################################
|
||||||
|
|
||||||
|
//write port
|
||||||
|
always @(posedge ext_clk)
|
||||||
|
if(ext_access)
|
||||||
|
ram[wr_addr[MAW-1:0]] <= ext_packet[DW-1:0];
|
||||||
|
|
||||||
|
//read port
|
||||||
|
always @ (posedge dut_clk)
|
||||||
|
begin
|
||||||
|
stim_packet[DW-1:0] <= ram[rd_addr[MAW-1:0]];
|
||||||
|
stim_read <= (rd_state==`STIM_ACTIVE); //mem-cycle adjust
|
||||||
|
end
|
||||||
|
|
||||||
|
//Shut off access immediately, but pipeline delay by one cycle
|
||||||
|
assign stim_access = stim_valid & stim_read & ~stim_done;
|
||||||
|
|
||||||
|
endmodule // stimulus
|
||||||
|
|
||||||
|
|
@ -5,24 +5,23 @@
|
|||||||
//# License: MIT (see LICENSE file in OH! repository) #
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
|
||||||
module oh_bin2onehot #(parameter DW = 32) // width of data inputs
|
module oh_bin2onehot #(parameter N = 2, // output vector width
|
||||||
(
|
parameter NB = $clog2(N) // binary encoded input
|
||||||
input [NB-1:0] in, // unsigned binary input
|
)
|
||||||
output [DW-1:0] out // one hot output vector
|
(
|
||||||
);
|
input [NB-1:0] in, // unsigned binary input
|
||||||
|
output [N-1:0] out // one hot output vector
|
||||||
parameter NB = $clog2(DW); // encoded bit width
|
);
|
||||||
|
|
||||||
integer i;
|
|
||||||
reg [DW-1:0] out;
|
|
||||||
|
|
||||||
always @*
|
|
||||||
for(i=0;i<DW;i=i+1)
|
|
||||||
out[i]=(in[NB-1:0]==i);
|
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
for(i=0;i<N;i=i+1) begin: gen_onehot
|
||||||
|
assign out[i] = (in[NB-1:0] == i);
|
||||||
|
end
|
||||||
endmodule // oh_bin2onehot
|
endmodule // oh_bin2onehot
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,19 +11,13 @@ module oh_buffer #(parameter N = 1, // number of inputs
|
|||||||
output [N-1:0] out // output
|
output [N-1:0] out // output
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC;
|
`ifdef CFG_ASIC
|
||||||
|
asic_buf #(.SIZE(SIZE)) ibuf [N-1:0] (.in(in[N-1:0]),
|
||||||
|
.out(out[N-1:0]));
|
||||||
|
`else
|
||||||
|
assign out[N-1:0] = in[N-1:0];
|
||||||
|
`endif
|
||||||
|
|
||||||
generate
|
|
||||||
if(ASIC)
|
|
||||||
begin : asic
|
|
||||||
asic_buf #(.SIZE(SIZE)) ibuf [N-1:0] (.in(in[N-1:0]),
|
|
||||||
.out(out[N-1:0]));
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin : generic
|
|
||||||
assign out[N-1:0] = in[N-1:0];
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
endmodule // oh_buffer
|
endmodule // oh_buffer
|
||||||
|
|
||||||
|
|
@ -7,35 +7,28 @@
|
|||||||
|
|
||||||
module oh_clockgate (
|
module oh_clockgate (
|
||||||
input clk, // clock input
|
input clk, // clock input
|
||||||
input te, // test enable enable
|
input te, // test enable
|
||||||
input en, // enable (from positive edge FF)
|
input en, // enable (from positive edge FF)
|
||||||
output eclk // enabled clock output
|
output eclk // enabled clock output
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC; // use ASIC lib
|
`ifdef CFG_ASIC
|
||||||
|
asic_icg icg (.en(en),
|
||||||
|
.te(te),
|
||||||
|
.clk(clk),
|
||||||
|
.eclk(eclk));
|
||||||
|
`else
|
||||||
|
wire en_sh;
|
||||||
|
wire en_sl;
|
||||||
|
//Stable low/valid rising edge enable
|
||||||
|
assign en_sl = en | te;
|
||||||
|
//Stable high enable signal
|
||||||
|
oh_lat0 lat0 (.out (en_sh),
|
||||||
|
.in (en_sl),
|
||||||
|
.clk (clk));
|
||||||
|
|
||||||
generate
|
assign eclk = clk & en_sh;
|
||||||
if(ASIC)
|
`endif // !`ifdef CFG_ASIC
|
||||||
begin : asic
|
|
||||||
asic_icg icg (.en(en),
|
|
||||||
.te(te),
|
|
||||||
.clk(clk),
|
|
||||||
.eclk(eclk));
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin : generic
|
|
||||||
wire en_sh;
|
|
||||||
wire en_sl;
|
|
||||||
//Stable low/valid rising edge enable
|
|
||||||
assign en_sl = en | te;
|
|
||||||
//Stable high enable signal
|
|
||||||
oh_lat0 lat0 (.out (en_sh),
|
|
||||||
.in (en_sl),
|
|
||||||
.clk (clk));
|
|
||||||
|
|
||||||
assign eclk = clk & en_sh;
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule // oh_clockgate
|
endmodule // oh_clockgate
|
||||||
|
|
@ -12,26 +12,25 @@ module oh_clockmux #(parameter N = 1) // number of clock inputs
|
|||||||
output clkout
|
output clkout
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC;
|
`ifdef CFG_ASIC
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if(ASIC& (N==2))
|
if((N==2))
|
||||||
begin : asic
|
begin : asic
|
||||||
asic_clockmux2 imux (.clkin(clkin[N-1:0]),
|
asic_clockmux2 imux (.clkin(clkin[N-1:0]),
|
||||||
.en(en[N-1:0]),
|
.en(en[N-1:0]),
|
||||||
.clkout(clkout));
|
.clkout(clkout));
|
||||||
end
|
end
|
||||||
else if(ASIC & (N==4))
|
else if((N==4))
|
||||||
begin : asic
|
begin : asic
|
||||||
asic_clockmux4 imux (.clkin(clkin[N-1:0]),
|
asic_clockmux4 imux (.clkin(clkin[N-1:0]),
|
||||||
.en(en[N-1:0]),
|
.en(en[N-1:0]),
|
||||||
.clkout(clkout));
|
.clkout(clkout));
|
||||||
end
|
end
|
||||||
else
|
|
||||||
begin : generic
|
|
||||||
assign clkout = |(clkin[N-1:0] & en[N-1:0]);
|
|
||||||
end
|
|
||||||
endgenerate
|
endgenerate
|
||||||
|
`else // !`ifdef CFG_ASIC
|
||||||
|
assign clkout = |(clkin[N-1:0] & en[N-1:0]);
|
||||||
|
`endif
|
||||||
|
|
||||||
endmodule // oh_clockmux
|
endmodule // oh_clockmux
|
||||||
|
|
||||||
|
|
@ -11,10 +11,9 @@ module oh_clockor #(parameter N = 1) // number of clock inputs
|
|||||||
output clkout
|
output clkout
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC;
|
`ifdef CFG_ASIC
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if(ASIC & (N==4))
|
if((N==4))
|
||||||
begin : asic
|
begin : asic
|
||||||
asic_clockor4 ior (/*AUTOINST*/
|
asic_clockor4 ior (/*AUTOINST*/
|
||||||
// Outputs
|
// Outputs
|
||||||
@ -23,20 +22,19 @@ module oh_clockor #(parameter N = 1) // number of clock inputs
|
|||||||
.clkin (clkin[3:0]));
|
.clkin (clkin[3:0]));
|
||||||
|
|
||||||
end // block: g0
|
end // block: g0
|
||||||
else if(ASIC & (N==2))
|
else if((N==2))
|
||||||
begin : asic
|
begin : asic
|
||||||
asic_clockor2 ior (/*AUTOINST*/
|
asic_clockor2 ior (/*AUTOINST*/
|
||||||
// Outputs
|
// Outputs
|
||||||
.clkout (clkout),
|
.clkout (clkout),
|
||||||
// Inputs
|
// Inputs
|
||||||
.clkin (clkin[1:0]));
|
.clkin (clkin[1:0]));
|
||||||
|
|
||||||
end // block: g0
|
|
||||||
else
|
|
||||||
begin : generic
|
|
||||||
assign clkout = |(clkin[N-1:0]);
|
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
`else
|
||||||
|
assign clkout = |(clkin[N-1:0]);
|
||||||
|
`endif
|
||||||
|
|
||||||
endmodule // oh_clockmux
|
endmodule // oh_clockmux
|
||||||
|
|
||||||
|
|
50
common/hdl/oh_counter.v
Normal file
50
common/hdl/oh_counter.v
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: Generic counter #
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
module oh_counter #(parameter DW = 32 // width of data inputs
|
||||||
|
)
|
||||||
|
(
|
||||||
|
//inputs
|
||||||
|
input clk, // clk input
|
||||||
|
input in, // input to count
|
||||||
|
input en, // enable counter
|
||||||
|
input dir,//0=increment, 1=decrement
|
||||||
|
input autowrap, //auto wrap around
|
||||||
|
input load, // load counter
|
||||||
|
input [DW-1:0] load_data, // input data to load
|
||||||
|
//outputs
|
||||||
|
output [DW-1:0] count, // count value
|
||||||
|
output wraparound // wraparound indicator
|
||||||
|
);
|
||||||
|
|
||||||
|
// local variables
|
||||||
|
reg [DW-1:0] count;
|
||||||
|
wire [DW-1:0] count_in;
|
||||||
|
|
||||||
|
//Select count direction
|
||||||
|
assign count_in[DW-1:0] = dir ? count[DW-1:0] - in :
|
||||||
|
count[DW-1:0] + in ;
|
||||||
|
|
||||||
|
// counter
|
||||||
|
always @(posedge clk)
|
||||||
|
if(load)
|
||||||
|
count[DW-1:0] <= load_data[DW-1:0];
|
||||||
|
else if (en & ~(wraparound & ~autowrap))
|
||||||
|
count[DW-1:0] <= count_in[DW-1:0];
|
||||||
|
|
||||||
|
// counter expired
|
||||||
|
assign wraparound = (dir & en & ~(|count[DW-1:0])) |
|
||||||
|
(~dir & en & (&count[DW-1:0]));
|
||||||
|
|
||||||
|
endmodule // oh_counter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,25 +14,22 @@ module oh_csa32 #(parameter DW = 1 // data width
|
|||||||
output [DW-1:0] c //carry
|
output [DW-1:0] c //carry
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC; // use asic library
|
`ifdef CFG_ASIC
|
||||||
|
genvar i;
|
||||||
generate
|
for (i=0;i<DW;i=i+1)
|
||||||
if(ASIC)
|
begin
|
||||||
begin : asic
|
asic_csa32 asic_csa32 (.s(s[i]),
|
||||||
asic_csa32 i_csa32[DW-1:0] (.s(s[DW-1:0]),
|
.c(c[i]),
|
||||||
.c(c[DW-1:0]),
|
.in2(in2[i]),
|
||||||
.in2(in2[DW-1:0]),
|
.in1(in1[i]),
|
||||||
.in1(in1[DW-1:0]),
|
.in0(in0[i]));
|
||||||
.in0(in0[DW-1:0]));
|
end
|
||||||
end
|
`else
|
||||||
else
|
assign s[DW-1:0] = in0[DW-1:0] ^ in1[DW-1:0] ^ in2[DW-1:0];
|
||||||
begin : generic
|
assign c[DW-1:0] = (in0[DW-1:0] & in1[DW-1:0]) |
|
||||||
assign s[DW-1:0] = in0[DW-1:0] ^ in1[DW-1:0] ^ in2[DW-1:0];
|
(in1[DW-1:0] & in2[DW-1:0]) |
|
||||||
assign c[DW-1:0] = (in0[DW-1:0] & in1[DW-1:0]) |
|
(in2[DW-1:0] & in0[DW-1:0] );
|
||||||
(in1[DW-1:0] & in2[DW-1:0]) |
|
`endif // !`ifdef CFG_ASIC
|
||||||
(in2[DW-1:0] & in0[DW-1:0] );
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule // oh_csa32
|
endmodule // oh_csa32
|
||||||
|
|
49
common/hdl/oh_csa42.v
Normal file
49
common/hdl/oh_csa42.v
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: Carry Save Adder (4:2) #
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
module oh_csa42 #( parameter DW = 1 // data width
|
||||||
|
)
|
||||||
|
( input [DW-1:0] in0, //input
|
||||||
|
input [DW-1:0] in1,//input
|
||||||
|
input [DW-1:0] in2,//input
|
||||||
|
input [DW-1:0] in3,//input
|
||||||
|
input cin,//intra stage carry in
|
||||||
|
output cout, //intra stage carry out (2x sum)
|
||||||
|
output [DW-1:0] s, //sum
|
||||||
|
output [DW-1:0] c //carry (=2x sum)
|
||||||
|
);
|
||||||
|
|
||||||
|
wire [DW-1:0] sum_int;
|
||||||
|
wire [DW:0] carry_int;
|
||||||
|
|
||||||
|
//Edges
|
||||||
|
assign carry_int[0] = cin;
|
||||||
|
assign cout = carry_int[DW];
|
||||||
|
|
||||||
|
//Full Adders
|
||||||
|
oh_csa32 #(.DW(DW))
|
||||||
|
fa0 (//inputs
|
||||||
|
.in0(in0[DW-1:0]),
|
||||||
|
.in1(in1[DW-1:0]),
|
||||||
|
.in2(in2[DW-1:0]),
|
||||||
|
//outputs
|
||||||
|
.c(carry_int[DW:1]),
|
||||||
|
.s(sum_int[DW-1:0]));
|
||||||
|
|
||||||
|
oh_csa32 #(.DW(DW))
|
||||||
|
fa1 (//inputs
|
||||||
|
.in0(in3[DW-1:0]),
|
||||||
|
.in1(sum_int[DW-1:0]),
|
||||||
|
.in2(carry_int[DW-1:0]),
|
||||||
|
//outputs
|
||||||
|
.c(c[DW-1:0]),
|
||||||
|
.s(s[DW-1:0]));
|
||||||
|
|
||||||
|
endmodule // oh_csa42
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4,9 +4,10 @@
|
|||||||
//# Author: Andreas Olofsson #
|
//# Author: Andreas Olofsson #
|
||||||
//# License: MIT (see LICENSE file in OH! repository) #
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
//
|
||||||
|
|
||||||
module oh_datagate #(parameter DW = 32, // width of data inputs
|
module oh_datagate #(parameter DW = 32, // width of data inputs
|
||||||
parameter PS = 3 // min quiet time before shutdown
|
parameter N = 3 // min quiet time before shutdown
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input clk, // clock
|
input clk, // clock
|
||||||
@ -15,15 +16,15 @@ module oh_datagate #(parameter DW = 32, // width of data inputs
|
|||||||
output [DW-1:0] dout // data output
|
output [DW-1:0] dout // data output
|
||||||
);
|
);
|
||||||
|
|
||||||
|
reg [N-1:0] enable_pipe;
|
||||||
reg [PS-1:0] enable_pipe;
|
wire enable;
|
||||||
wire enable;
|
|
||||||
|
|
||||||
always @ (posedge clk)
|
always @ (posedge clk)
|
||||||
enable_pipe[PS-1:0] <= {enable_pipe[PS-2:0],en};
|
enable_pipe[N-1:0] <= {enable_pipe[N-2:0],en};
|
||||||
|
|
||||||
assign enable = {enable_pipe[PS-1:0],en};
|
//Mask to 0 if no valid for last N cycles
|
||||||
|
assign enable = en | (|enable_pipe[N-1:0]);
|
||||||
|
|
||||||
assign dout[DW-1:0] = {(DW){enable}} & din[DW-1:0];
|
assign dout[DW-1:0] = {(DW){enable}} & din[DW-1:0];
|
||||||
|
|
||||||
endmodule // oh_datagate
|
endmodule // oh_datagate
|
34
common/hdl/oh_delay.v
Normal file
34
common/hdl/oh_delay.v
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: Delays input signal by N clock cycles #
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
module oh_delay #(parameter DW = 1, // width of data
|
||||||
|
parameter N = 1 // clock cycle delay by
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input [DW-1:0] in, // input
|
||||||
|
input clk,//clock input
|
||||||
|
output [DW-1:0] out // output
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [DW-1:0] sync_pipe[N-1:0];
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
always @ (posedge clk)
|
||||||
|
sync_pipe[0]<=in[DW-1:0];
|
||||||
|
for(i=1;i<N;i=i+1) begin: gen_pipe
|
||||||
|
always @ (posedge clk)
|
||||||
|
sync_pipe[i]<=sync_pipe[i-1];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
assign out[DW-1:0] = sync_pipe[N-1];
|
||||||
|
|
||||||
|
endmodule // oh_delay
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
|||||||
//#############################################################################
|
//#############################################################################
|
||||||
|
|
||||||
module oh_dsync #(parameter PS = 2, // number of sync stages
|
module oh_dsync #(parameter PS = 2, // number of sync stages
|
||||||
parameter DELAY = 0 // random delay
|
parameter DELAY = 0 // random delay
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input clk, // clock
|
input clk, // clock
|
||||||
@ -15,29 +15,22 @@ module oh_dsync #(parameter PS = 2, // number of sync stages
|
|||||||
output dout // synchronized data
|
output dout // synchronized data
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC; // use asic library
|
`ifdef CFG_ASIC
|
||||||
|
asic_dsync asic_dsync (.clk(clk),
|
||||||
generate
|
.nreset(nreset),
|
||||||
if(ASIC)
|
.din(din),
|
||||||
begin : g0
|
.dout(dout));
|
||||||
asic_dsync asic_dsync (.clk(clk),
|
`else
|
||||||
.nreset(nreset),
|
reg [PS:0] sync_pipe;
|
||||||
.din(din),
|
always @ (posedge clk or negedge nreset)
|
||||||
.dout(dout));
|
if(!nreset)
|
||||||
end
|
sync_pipe[PS:0] <= 'b0;
|
||||||
else
|
else
|
||||||
begin : g0
|
sync_pipe[PS:0] <= {sync_pipe[PS-1:0],din};
|
||||||
reg [PS:0] sync_pipe;
|
// drive randomize delay from testbench
|
||||||
always @ (posedge clk or negedge nreset)
|
assign dout = (DELAY & sync_pipe[PS]) | //extra cycle
|
||||||
if(!nreset)
|
(~DELAY & sync_pipe[PS-1]); //default
|
||||||
sync_pipe[PS:0] <= 1'b0;
|
`endif // !`ifdef CFG_ASIC
|
||||||
else
|
|
||||||
sync_pipe[PS:0] <= {sync_pipe[PS-1:0],din};
|
|
||||||
// drive randomize delay from testbench
|
|
||||||
assign dout = (DELAY & sync_pipe[PS]) | //extra cycle
|
|
||||||
(~DELAY & sync_pipe[PS-1]); //default
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule // oh_dsync
|
endmodule // oh_dsync
|
||||||
|
|
@ -13,12 +13,15 @@ module oh_fifo_async # (parameter DW = 104, // FIFO width
|
|||||||
)
|
)
|
||||||
(
|
(
|
||||||
input nreset, // async reset
|
input nreset, // async reset
|
||||||
|
//Write Side
|
||||||
input wr_clk, // write clock
|
input wr_clk, // write clock
|
||||||
input wr_en, // write fifo
|
input wr_en, // write fifo
|
||||||
input [DW-1:0] din, // data to write
|
input [DW-1:0] din, // data to write
|
||||||
|
//Read Side
|
||||||
input rd_clk, // read clock
|
input rd_clk, // read clock
|
||||||
input rd_en, // read fifo
|
input rd_en, // read fifo
|
||||||
output [DW-1:0] dout, // output data (next cycle)
|
output [DW-1:0] dout, // output data (next cycle)
|
||||||
|
//Status
|
||||||
output full, // fifo is full
|
output full, // fifo is full
|
||||||
output prog_full, // fifo reaches full threshold
|
output prog_full, // fifo reaches full threshold
|
||||||
output empty, // fifo is empty
|
output empty, // fifo is empty
|
||||||
@ -29,45 +32,7 @@ module oh_fifo_async # (parameter DW = 104, // FIFO width
|
|||||||
wire [AW-1:0] wr_count; // valid entries in fifo
|
wire [AW-1:0] wr_count; // valid entries in fifo
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if(TARGET=="GENERIC") begin : basic
|
if (TARGET=="XILINX") begin : xilinx
|
||||||
oh_fifo_generic #(.DEPTH(DEPTH),
|
|
||||||
.DW(DW))
|
|
||||||
fifo_generic (
|
|
||||||
// Outputs
|
|
||||||
.full (full),
|
|
||||||
.prog_full (prog_full),
|
|
||||||
.dout (dout[DW-1:0]),
|
|
||||||
.empty (empty),
|
|
||||||
.rd_count (rd_count[AW-1:0]),
|
|
||||||
.wr_count (wr_count[AW-1:0]),
|
|
||||||
// Inputs
|
|
||||||
.nreset (nreset),
|
|
||||||
.wr_clk (wr_clk),
|
|
||||||
.rd_clk (rd_clk),
|
|
||||||
.wr_en (wr_en),
|
|
||||||
.din (din[DW-1:0]),
|
|
||||||
.rd_en (rd_en));
|
|
||||||
end
|
|
||||||
else if(TARGET=="ASIC") begin : asic
|
|
||||||
oh_fifo_generic #(.DEPTH(DEPTH),
|
|
||||||
.DW(DW))
|
|
||||||
fifo_generic (
|
|
||||||
// Outputs
|
|
||||||
.full (full),
|
|
||||||
.prog_full (prog_full),
|
|
||||||
.dout (dout[DW-1:0]),
|
|
||||||
.empty (empty),
|
|
||||||
.rd_count (rd_count[AW-1:0]),
|
|
||||||
.wr_count (wr_count[AW-1:0]),
|
|
||||||
// Inputs
|
|
||||||
.nreset (nreset),
|
|
||||||
.wr_clk (wr_clk),
|
|
||||||
.rd_clk (rd_clk),
|
|
||||||
.wr_en (wr_en),
|
|
||||||
.din (din[DW-1:0]),
|
|
||||||
.rd_en (rd_en));
|
|
||||||
end
|
|
||||||
else if (TARGET=="XILINX") begin : xilinx
|
|
||||||
if((DW==104) & (DEPTH==32))
|
if((DW==104) & (DEPTH==32))
|
||||||
begin : g104x32
|
begin : g104x32
|
||||||
fifo_async_104x32
|
fifo_async_104x32
|
||||||
@ -86,7 +51,27 @@ module oh_fifo_async # (parameter DW = 104, // FIFO width
|
|||||||
.din (din[DW-1:0]),
|
.din (din[DW-1:0]),
|
||||||
.rd_en (rd_en));
|
.rd_en (rd_en));
|
||||||
end // if ((DW==104) & (DEPTH==32))
|
end // if ((DW==104) & (DEPTH==32))
|
||||||
end // block: xilinx
|
end
|
||||||
|
else begin : generic
|
||||||
|
oh_fifo_generic #(.DEPTH(DEPTH),
|
||||||
|
.DW(DW))
|
||||||
|
fifo_generic (
|
||||||
|
// Outputs
|
||||||
|
.full (full),
|
||||||
|
.prog_full (prog_full),
|
||||||
|
.dout (dout[DW-1:0]),
|
||||||
|
.empty (empty),
|
||||||
|
.rd_count (rd_count[AW-1:0]),
|
||||||
|
.wr_count (wr_count[AW-1:0]),
|
||||||
|
// Inputs
|
||||||
|
.nreset (nreset),
|
||||||
|
.wr_clk (wr_clk),
|
||||||
|
.rd_clk (rd_clk),
|
||||||
|
.wr_en (wr_en),
|
||||||
|
.din (din[DW-1:0]),
|
||||||
|
.rd_en (rd_en));
|
||||||
|
end
|
||||||
|
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
endmodule // oh_fifo_async
|
endmodule // oh_fifo_async
|
@ -10,24 +10,26 @@ module oh_fifo_cdc # (parameter DW = 104, //FIFO width
|
|||||||
parameter TARGET = "GENERIC" //XILINX,ALTERA,GENERIC
|
parameter TARGET = "GENERIC" //XILINX,ALTERA,GENERIC
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input nreset, // shared domain async active low reset
|
input nreset, // async active low reset
|
||||||
input clk_in, // write clock
|
//Write Side
|
||||||
input access_in, // write access
|
input clk_in, // write clock
|
||||||
input [DW-1:0] packet_in, // write packet
|
input valid_in, // write valid
|
||||||
output wait_out, // write pushback
|
input [DW-1:0] packet_in, // write packet
|
||||||
input clk_out, //read clock
|
output ready_out, // write pushback
|
||||||
output reg access_out, //read access
|
//Read Side
|
||||||
output [DW-1:0] packet_out, //read packet
|
input clk_out, //read clock
|
||||||
input wait_in, // read pushback
|
output reg valid_out, //read valid
|
||||||
output prog_full, // fifo is half full
|
output [DW-1:0] packet_out, //read packet
|
||||||
output full, // fifo is full
|
input ready_in, // read pushback
|
||||||
output empty // fifo is empty
|
//Status
|
||||||
|
output prog_full, // fifo is half full
|
||||||
|
output full, // fifo is full
|
||||||
|
output empty // fifo is empty
|
||||||
);
|
);
|
||||||
|
|
||||||
// local wires
|
// local wires
|
||||||
wire wr_en;
|
wire wr_en;
|
||||||
wire rd_en;
|
wire rd_en;
|
||||||
wire io_nreset;
|
|
||||||
|
|
||||||
// parametric async fifo
|
// parametric async fifo
|
||||||
oh_fifo_async #(.TARGET(TARGET),
|
oh_fifo_async #(.TARGET(TARGET),
|
||||||
@ -46,21 +48,21 @@ module oh_fifo_cdc # (parameter DW = 104, //FIFO width
|
|||||||
.rd_en (rd_en));
|
.rd_en (rd_en));
|
||||||
|
|
||||||
// FIFO control logic
|
// FIFO control logic
|
||||||
assign wr_en = access_in;
|
assign wr_en = valid_in;
|
||||||
assign rd_en = ~empty & ~wait_in;
|
assign rd_en = ~empty & ready_in;
|
||||||
assign wait_out = prog_full; //wait_out should stall access_in signal
|
assign ready_out = ~prog_full;
|
||||||
|
|
||||||
// pipeline access_out signal
|
//async asser, sync deassert of reset
|
||||||
always @ (posedge clk_out or negedge io_nreset)
|
oh_rsync sync_reset(.nrst_out (nreset_out),
|
||||||
if(!io_nreset)
|
.clk (clk_out),
|
||||||
access_out <= 1'b0;
|
.nrst_in (nreset));
|
||||||
else if(~wait_in)
|
|
||||||
access_out <= rd_en;
|
|
||||||
|
|
||||||
// be safe, synchronize reset with clk_out
|
//align valid signal with FIFO read delay
|
||||||
oh_rsync sync_reset(.nrst_out (io_nreset),
|
always @ (posedge clk_out or negedge nreset_out)
|
||||||
.clk (clk_out),
|
if(!nreset_out)
|
||||||
.nrst_in (nreset));
|
valid_out <= 1'b0;
|
||||||
|
else if(ready_in)
|
||||||
|
valid_out <= rd_en;
|
||||||
|
|
||||||
endmodule // oh_fifo_cdc
|
endmodule // oh_fifo_cdc
|
||||||
|
|
146
common/hdl/oh_fifo_sync.v
Normal file
146
common/hdl/oh_fifo_sync.v
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: Synchronous FIFO #
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
module oh_fifo_sync
|
||||||
|
#(parameter DW = 104, // FIFO width
|
||||||
|
parameter DEPTH = 32, // FIFO depth
|
||||||
|
parameter REG = 1, // Register fifo output
|
||||||
|
parameter AW = $clog2(DEPTH),// rd_count width (derived)
|
||||||
|
parameter PROGFULL = DEPTH-1, // programmable almost full level
|
||||||
|
parameter TYPE = "soft", // hard=hard macro,soft=synthesizable
|
||||||
|
parameter CONFIG = "default", // hard macro user config pass through
|
||||||
|
parameter SHAPE = "square" // hard macro shape (square, tall, wide)
|
||||||
|
)
|
||||||
|
(
|
||||||
|
//basic interface
|
||||||
|
input clk, // clock
|
||||||
|
input nreset, //async reset
|
||||||
|
input clear, //clear fifo (synchronous)
|
||||||
|
//write port
|
||||||
|
input [DW-1:0] din, // data to write
|
||||||
|
input wr_en, // write fifo
|
||||||
|
output full, // fifo full
|
||||||
|
output almost_full, //progfull level reached
|
||||||
|
//read port
|
||||||
|
input rd_en, // read fifo
|
||||||
|
output [DW-1:0] dout, // output data (next cycle)
|
||||||
|
output empty, // fifo is empty
|
||||||
|
output reg [AW-1:0] rd_count, // valid entries in fifo
|
||||||
|
// BIST interface
|
||||||
|
input bist_en, // bist enable
|
||||||
|
input bist_we, // write enable global signal
|
||||||
|
input [DW-1:0] bist_wem, // write enable vector
|
||||||
|
input [AW-1:0] bist_addr, // address
|
||||||
|
input [DW-1:0] bist_din, // data input
|
||||||
|
input [DW-1:0] bist_dout, // data input
|
||||||
|
// Power/repair (hard macro only)
|
||||||
|
input shutdown, // shutdown signal
|
||||||
|
input vss, // ground signal
|
||||||
|
input vdd, // memory array power
|
||||||
|
input vddio, // periphery/io power
|
||||||
|
input [7:0] memconfig, // generic memory config
|
||||||
|
input [7:0] memrepair // repair vector
|
||||||
|
);
|
||||||
|
|
||||||
|
//############################
|
||||||
|
//local wires
|
||||||
|
//############################
|
||||||
|
reg [AW:0] wr_addr;
|
||||||
|
reg [AW:0] rd_addr;
|
||||||
|
wire fifo_read;
|
||||||
|
wire fifo_write;
|
||||||
|
wire ptr_match;
|
||||||
|
wire fifo_empty;
|
||||||
|
|
||||||
|
//############################
|
||||||
|
// FIFO Control
|
||||||
|
//############################
|
||||||
|
assign fifo_read = rd_en & ~empty;
|
||||||
|
assign fifo_write = wr_en & ~full;
|
||||||
|
assign almost_full = (rd_count[AW-1:0] == PROGFULL);
|
||||||
|
assign ptr_match = (wr_addr[AW-1:0] == rd_addr[AW-1:0]);
|
||||||
|
assign full = ptr_match & (wr_addr[AW]==!rd_addr[AW]);
|
||||||
|
assign fifo_empty = ptr_match & (wr_addr[AW]==rd_addr[AW]);
|
||||||
|
|
||||||
|
always @ (posedge clk or negedge nreset)
|
||||||
|
if(~nreset)
|
||||||
|
begin
|
||||||
|
wr_addr[AW:0] <= 'd0;
|
||||||
|
rd_addr[AW:0] <= 'b0;
|
||||||
|
rd_count[AW-1:0] <= 'b0;
|
||||||
|
end
|
||||||
|
else if(clear)
|
||||||
|
begin
|
||||||
|
wr_addr[AW:0] <= 'd0;
|
||||||
|
rd_addr[AW:0] <= 'b0;
|
||||||
|
rd_count[AW-1:0] <= 'b0;
|
||||||
|
end
|
||||||
|
else if(fifo_write & fifo_read)
|
||||||
|
begin
|
||||||
|
wr_addr[AW:0] <= wr_addr[AW:0] + 'd1;
|
||||||
|
rd_addr[AW:0] <= rd_addr[AW:0] + 'd1;
|
||||||
|
end
|
||||||
|
else if(fifo_write)
|
||||||
|
begin
|
||||||
|
wr_addr[AW:0] <= wr_addr[AW:0] + 'd1;
|
||||||
|
rd_count[AW-1:0]<= rd_count[AW-1:0] + 'd1;
|
||||||
|
end
|
||||||
|
else if(fifo_read)
|
||||||
|
begin
|
||||||
|
rd_addr[AW:0] <= rd_addr[AW:0] + 'd1;
|
||||||
|
rd_count[AW-1:0]<= rd_count[AW-1:0] - 'd1;
|
||||||
|
end
|
||||||
|
|
||||||
|
//Pipeline register to account for RAM output register
|
||||||
|
reg empty_reg;
|
||||||
|
always @ (posedge clk)
|
||||||
|
empty_reg <= fifo_empty;
|
||||||
|
|
||||||
|
assign empty = (REG==1) ? empty_reg :
|
||||||
|
fifo_empty;
|
||||||
|
//############################
|
||||||
|
// Dual Ported Memory
|
||||||
|
//############################
|
||||||
|
oh_memory
|
||||||
|
#(.DUALPORT(1),
|
||||||
|
.DW (DW),
|
||||||
|
.DEPTH (DEPTH),
|
||||||
|
.REG (REG),
|
||||||
|
.TYPE (TYPE),
|
||||||
|
.CONFIG (CONFIG),
|
||||||
|
.SHAPE (SHAPE))
|
||||||
|
oh_memory (// read port
|
||||||
|
.rd_dout (dout[DW-1:0]),
|
||||||
|
.rd_clk (clk),
|
||||||
|
.rd_en (fifo_read),
|
||||||
|
.rd_addr (rd_addr[AW-1:0]),
|
||||||
|
// write port
|
||||||
|
.wr_clk (clk),
|
||||||
|
.wr_en (fifo_write),
|
||||||
|
.wr_wem ({(DW){1'b1}}),
|
||||||
|
.wr_addr (wr_addr[AW-1:0]),
|
||||||
|
.wr_din (din[DW-1:0]),
|
||||||
|
/*AUTOINST*/
|
||||||
|
// Inputs
|
||||||
|
.bist_en (bist_en),
|
||||||
|
.bist_we (bist_we),
|
||||||
|
.bist_wem (bist_wem[DW-1:0]),
|
||||||
|
.bist_addr (bist_addr[AW-1:0]),
|
||||||
|
.bist_din (bist_din[DW-1:0]),
|
||||||
|
.bist_dout (bist_dout[DW-1:0]),
|
||||||
|
.shutdown (shutdown),
|
||||||
|
.vss (vss),
|
||||||
|
.vdd (vdd),
|
||||||
|
.vddio (vddio),
|
||||||
|
.memconfig (memconfig[7:0]),
|
||||||
|
.memrepair (memrepair[7:0]));
|
||||||
|
|
||||||
|
endmodule // oh_fifo_sync
|
||||||
|
|
||||||
|
// Local Variables:
|
||||||
|
// verilog-library-directories:("." "../dv" "../../fpu/hdl" "../../../oh/common/hdl")
|
||||||
|
// End:
|
51
common/hdl/oh_iddr.v
Normal file
51
common/hdl/oh_iddr.v
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: Dual data rate input buffer (2 cycle delay) #
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
module oh_iddr #(parameter DW = 1 // width of data inputs
|
||||||
|
)
|
||||||
|
(
|
||||||
|
input clk, // clock
|
||||||
|
input ce0, // 1st cycle enable
|
||||||
|
input ce1, // 2nd cycle enable
|
||||||
|
input [DW/2-1:0] din, // data input sampled on both edges of clock
|
||||||
|
output reg [DW-1:0] dout // iddr aligned
|
||||||
|
);
|
||||||
|
|
||||||
|
//regs("sl"=stable low, "sh"=stable high)
|
||||||
|
reg [DW/2-1:0] din_sl;
|
||||||
|
reg [DW/2-1:0] din_sh;
|
||||||
|
reg ce0_negedge;
|
||||||
|
|
||||||
|
//########################
|
||||||
|
// Pipeline valid for negedge
|
||||||
|
//########################
|
||||||
|
always @ (negedge clk)
|
||||||
|
ce0_negedge <= ce0;
|
||||||
|
|
||||||
|
//########################
|
||||||
|
// Dual edge sampling
|
||||||
|
//########################
|
||||||
|
|
||||||
|
always @ (posedge clk)
|
||||||
|
if(ce0)
|
||||||
|
din_sl[DW/2-1:0] <= din[DW/2-1:0];
|
||||||
|
always @ (negedge clk)
|
||||||
|
if(ce0_negedge)
|
||||||
|
din_sh[DW/2-1:0] <= din[DW/2-1:0];
|
||||||
|
|
||||||
|
//########################
|
||||||
|
// Aign pipeline
|
||||||
|
//########################
|
||||||
|
always @ (posedge clk)
|
||||||
|
if(ce1)
|
||||||
|
dout[DW-1:0] <= {din_sh[DW/2-1:0],
|
||||||
|
din_sl[DW/2-1:0]};
|
||||||
|
|
||||||
|
endmodule // oh_iddr
|
||||||
|
|
||||||
|
|
||||||
|
|
44
common/hdl/oh_iobuf.v
Normal file
44
common/hdl/oh_iobuf.v
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: IO Buffer #
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
module oh_iobuf #(parameter N = 1, // BUS WIDTH
|
||||||
|
parameter TYPE = "BEHAVIORAL" // BEHAVIORAL, HARD
|
||||||
|
)
|
||||||
|
(
|
||||||
|
//POWER
|
||||||
|
inout vdd, // core supply
|
||||||
|
inout vddio,// io supply
|
||||||
|
inout vss, // ground
|
||||||
|
//CONTROLS
|
||||||
|
input enpullup, //enable pullup
|
||||||
|
input enpulldown, //enable pulldown
|
||||||
|
input slewlimit, //slew limiter
|
||||||
|
input [3:0] drivestrength, //drive strength
|
||||||
|
//DATA
|
||||||
|
input [N-1:0] ie, //input enable
|
||||||
|
input [N-1:0] oe, //output enable
|
||||||
|
output [N-1:0] out,//output to core
|
||||||
|
input [N-1:0] in, //input from core
|
||||||
|
//BIDIRECTIONAL PAD
|
||||||
|
inout [N-1:0] pad
|
||||||
|
);
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
|
||||||
|
//TODO: Model power signals
|
||||||
|
for (i = 0; i < N; i = i + 1) begin : gen_buf
|
||||||
|
if(TYPE=="BEHAVIORAL") begin : gen_beh
|
||||||
|
assign pad[i] = oe[i] ? in[i] : 1'bZ;
|
||||||
|
assign out[i] = ie[i] ? pad[i] : 1'b0;
|
||||||
|
end
|
||||||
|
else begin : gen_custom
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule // oh_iobuf
|
||||||
|
|
||||||
|
|
@ -12,24 +12,18 @@ module oh_lat0 #(parameter DW = 1 // data width
|
|||||||
output [DW-1:0] out // output data (stable/latched when clk=1)
|
output [DW-1:0] out // output data (stable/latched when clk=1)
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC; // use ASIC lib
|
|
||||||
|
|
||||||
generate
|
`ifdef CFG_ASIC
|
||||||
if(ASIC)
|
asic_lat0 ilat [DW-1:0] (.clk(clk),
|
||||||
begin : g0
|
.in(in[DW-1:0]),
|
||||||
asic_lat0 ilat [DW-1:0] (.clk(clk),
|
|
||||||
.in(in[DW-1:0]),
|
|
||||||
.out(out[DW-1:0]));
|
.out(out[DW-1:0]));
|
||||||
end
|
`else
|
||||||
else
|
reg [DW-1:0] out_reg;
|
||||||
begin : g0
|
always_latch
|
||||||
reg [DW-1:0] out_reg;
|
if (!clk)
|
||||||
always @ (clk or in)
|
out_reg[DW-1:0] <= in[DW-1:0];
|
||||||
if (!clk)
|
assign out[DW-1:0] = out_reg[DW-1:0];
|
||||||
out_reg[DW-1:0] <= in[DW-1:0];
|
`endif
|
||||||
assign out[DW-1:0] = out_reg[DW-1:0];
|
|
||||||
end // else: !if(ASIC)
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule // oh_lat0
|
endmodule // oh_lat0
|
||||||
|
|
@ -12,23 +12,16 @@ module oh_lat1 #(parameter DW = 1 //data width
|
|||||||
output [DW-1:0] out // output data (stable/latched when clk=0)
|
output [DW-1:0] out // output data (stable/latched when clk=0)
|
||||||
);
|
);
|
||||||
|
|
||||||
localparam ASIC = `CFG_ASIC; // use ASIC lib
|
`ifdef CFG_ASIC
|
||||||
|
asic_lat1 i_lat [DW-1:0] (.clk(clk),
|
||||||
generate
|
.in(in[DW-1:0]),
|
||||||
if(ASIC)
|
.out(out[DW-1:0]));
|
||||||
begin : g0
|
`else
|
||||||
asic_lat1 i_lat [DW-1:0] (.clk(clk),
|
reg [DW-1:0] out_reg;
|
||||||
.in(in[DW-1:0]),
|
always_latch
|
||||||
.out(out[DW-1:0]));
|
if (clk)
|
||||||
end
|
out_reg[DW-1:0] <= in[DW-1:0];
|
||||||
else
|
assign out[DW-1:0] = out_reg[DW-1:0];
|
||||||
begin : g0
|
`endif
|
||||||
reg [DW-1:0] out_reg;
|
|
||||||
always @ (clk or in)
|
|
||||||
if (clk)
|
|
||||||
out_reg[DW-1:0] <= in[DW-1:0];
|
|
||||||
assign out[DW-1:0] = out_reg[DW-1:0];
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
endmodule // oh_lat1
|
endmodule // oh_lat1
|
96
common/hdl/oh_mem_dp.v
Normal file
96
common/hdl/oh_mem_dp.v
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: Dual Ported Memory #
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
module oh_memory_dp
|
||||||
|
#(parameter DW = 104, // FIFO width
|
||||||
|
parameter DEPTH = 32, // FIFO depth
|
||||||
|
parameter REG = 1, // Register fifo output
|
||||||
|
parameter AW = $clog2(DEPTH),// rd_count width (derived)
|
||||||
|
parameter TYPE = "soft", // hard (macro) or soft (rtl)
|
||||||
|
parameter SHAPE = "square" // hard macro shape (square, tall, wide)
|
||||||
|
)
|
||||||
|
(// Memory interface (dual port)
|
||||||
|
input wr_clk, //write clock
|
||||||
|
input wr_en, //write enable
|
||||||
|
input [DW-1:0] wr_wem, //per bit write enable
|
||||||
|
input [AW-1:0] wr_addr,//write address
|
||||||
|
input [DW-1:0] wr_din, //write data
|
||||||
|
input rd_clk, //read clock
|
||||||
|
input rd_en, //read enable
|
||||||
|
input [AW-1:0] rd_addr,//read address
|
||||||
|
output [DW-1:0] rd_dout,//read output data
|
||||||
|
// BIST interface
|
||||||
|
input bist_en, // bist enable
|
||||||
|
input bist_we, // write enable global signal
|
||||||
|
input [DW-1:0] bist_wem, // write enable vector
|
||||||
|
input [AW-1:0] bist_addr, // address
|
||||||
|
input [DW-1:0] bist_din, // data input
|
||||||
|
// Power/repair (hard macro only)
|
||||||
|
input shutdown, // shutdown signal
|
||||||
|
input vss, // ground signal
|
||||||
|
input vdd, // memory array power
|
||||||
|
input vddio, // periphery/io power
|
||||||
|
input [7:0] memconfig, // generic memory config
|
||||||
|
input [7:0] memrepair // repair vector
|
||||||
|
);
|
||||||
|
|
||||||
|
generate
|
||||||
|
|
||||||
|
if(TYPE=="soft") begin: soft
|
||||||
|
oh_memory_soft
|
||||||
|
//#########################################
|
||||||
|
// Generic RAM for synthesis
|
||||||
|
//#########################################
|
||||||
|
//local variables
|
||||||
|
reg [DW-1:0] ram [0:DEPTH-1];
|
||||||
|
wire [DW-1:0] rdata;
|
||||||
|
integer i;
|
||||||
|
|
||||||
|
//write port
|
||||||
|
always @(posedge wr_clk)
|
||||||
|
for (i=0;i<DW;i=i+1)
|
||||||
|
if (wr_en & wr_wem[i])
|
||||||
|
ram[wr_addr[AW-1:0]][i] <= wr_din[i];
|
||||||
|
//read port
|
||||||
|
assign rdata[DW-1:0] = ram[rd_addr[AW-1:0]];
|
||||||
|
|
||||||
|
//Configurable output register
|
||||||
|
reg [DW-1:0] rd_reg;
|
||||||
|
always @ (posedge rd_clk)
|
||||||
|
if(rd_en)
|
||||||
|
rd_reg[DW-1:0] <= rdata[DW-1:0];
|
||||||
|
|
||||||
|
//Drive output from register or RAM directly
|
||||||
|
assign rd_dout[DW-1:0] = (REG==1) ? rd_reg[DW-1:0] :
|
||||||
|
rdata[DW-1:0];
|
||||||
|
end // block: soft
|
||||||
|
else begin: hard
|
||||||
|
//#########################################
|
||||||
|
// Hard coded RAM Macros
|
||||||
|
//#########################################
|
||||||
|
oh_memory_hard #(.DW(DW),
|
||||||
|
.DEPTH(DEPTH),
|
||||||
|
.SHAPE(SHAPE)
|
||||||
|
.REG(REG))
|
||||||
|
asic_mem_dp (//read port
|
||||||
|
.rd_dout (rd_dout[DW-1:0]),
|
||||||
|
.rd_clk (rd_clk),
|
||||||
|
.rd_en (rd_en),
|
||||||
|
.rd_addr (rd_addr[AW-1:0]),
|
||||||
|
//write port
|
||||||
|
.wr_en (wr_en),
|
||||||
|
.wr_clk (wr_clk),
|
||||||
|
.wr_addr (wr_addr[AW-1:0]),
|
||||||
|
.wr_wem (wr_wem[DW-1:0]),
|
||||||
|
.wr_din (wr_din[DW-1:0]));
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
|
||||||
|
endmodule // oh_memory_dp
|
||||||
|
|
||||||
|
|
||||||
|
|
115
common/hdl/oh_memory.v
Normal file
115
common/hdl/oh_memory.v
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
//#############################################################################
|
||||||
|
//# Function: Configurable Memory
|
||||||
|
//#############################################################################
|
||||||
|
//# Author: Andreas Olofsson #
|
||||||
|
//# License: MIT (see LICENSE file in OH! repository) #
|
||||||
|
//#############################################################################
|
||||||
|
|
||||||
|
module oh_memory
|
||||||
|
#(parameter DW = 104, // FIFO width
|
||||||
|
parameter DEPTH = 32, // FIFO depth
|
||||||
|
parameter REG = 1, // Register fifo output
|
||||||
|
parameter AW = $clog2(DEPTH),// rd_count width (derived)
|
||||||
|
parameter TYPE = "soft", // hard=hard macro,soft=synthesizable
|
||||||
|
parameter DUALPORT= "1", // 1=dual port,0=single port
|
||||||
|
parameter CONFIG = "default", // hard macro user config pass through
|
||||||
|
parameter SHAPE = "square" // hard macro shape (square, tall, wide)
|
||||||
|
)
|
||||||
|
(// Memory interface (dual port)
|
||||||
|
input wr_clk, //write clock
|
||||||
|
input wr_en, //write enable
|
||||||
|
input [DW-1:0] wr_wem, //per bit write enable
|
||||||
|
input [AW-1:0] wr_addr,//write address
|
||||||
|
input [DW-1:0] wr_din, //write data
|
||||||
|
input rd_clk, //read clock
|
||||||
|
input rd_en, //read enable
|
||||||
|
input [AW-1:0] rd_addr,//read address (only used for dual port!)
|
||||||
|
output [DW-1:0] rd_dout,//read output data
|
||||||
|
// BIST interface
|
||||||
|
input bist_en, // bist enable
|
||||||
|
input bist_we, // write enable global signal
|
||||||
|
input [DW-1:0] bist_wem, // write enable vector
|
||||||
|
input [AW-1:0] bist_addr, // address
|
||||||
|
input [DW-1:0] bist_din, // data input
|
||||||
|
input [DW-1:0] bist_dout, // data input
|
||||||
|
// Power/repair (hard macro only)
|
||||||
|
input shutdown, // shutdown signal
|
||||||
|
input vss, // ground signal
|
||||||
|
input vdd, // memory array power
|
||||||
|
input vddio, // periphery/io power
|
||||||
|
input [7:0] memconfig, // generic memory config
|
||||||
|
input [7:0] memrepair // repair vector
|
||||||
|
);
|
||||||
|
|
||||||
|
generate
|
||||||
|
if(TYPE=="soft") begin: ram_soft
|
||||||
|
oh_ram #(.DW(DW),
|
||||||
|
.DEPTH(DEPTH),
|
||||||
|
.REG(REG),
|
||||||
|
.DUALPORT(DUALPORT))
|
||||||
|
oh_ram(/*AUTOINST*/
|
||||||
|
// Outputs
|
||||||
|
.rd_dout (rd_dout[DW-1:0]),
|
||||||
|
// Inputs
|
||||||
|
.rd_clk (rd_clk),
|
||||||
|
.rd_en (rd_en),
|
||||||
|
.rd_addr (rd_addr[AW-1:0]),
|
||||||
|
.wr_clk (wr_clk),
|
||||||
|
.wr_en (wr_en),
|
||||||
|
.wr_addr (wr_addr[AW-1:0]),
|
||||||
|
.wr_wem (wr_wem[DW-1:0]),
|
||||||
|
.wr_din (wr_din[DW-1:0]),
|
||||||
|
.bist_en (bist_en),
|
||||||
|
.bist_we (bist_we),
|
||||||
|
.bist_wem (bist_wem[DW-1:0]),
|
||||||
|
.bist_addr (bist_addr[AW-1:0]),
|
||||||
|
.bist_din (bist_din[DW-1:0]),
|
||||||
|
.bist_dout (bist_dout[DW-1:0]),
|
||||||
|
.shutdown (shutdown),
|
||||||
|
.vss (vss),
|
||||||
|
.vdd (vdd),
|
||||||
|
.vddio (vddio),
|
||||||
|
.memconfig (memconfig[7:0]),
|
||||||
|
.memrepair (memrepair[7:0]));
|
||||||
|
end // block: soft
|
||||||
|
else begin: ram_hard
|
||||||
|
//#########################################
|
||||||
|
// Hard coded RAM Macros
|
||||||
|
//#########################################
|
||||||
|
asic_ram #(.DW(DW),
|
||||||
|
.DEPTH(DEPTH),
|
||||||
|
.REG(REG),
|
||||||
|
.DUALPORT(DUALPORT),
|
||||||
|
.CONFIG(CONFIG),
|
||||||
|
.SHAPE(SHAPE))
|
||||||
|
asic_ram(
|
||||||
|
// Outputs
|
||||||
|
.rd_dout (rd_dout[DW-1:0]),
|
||||||
|
// Inputs
|
||||||
|
.rd_clk (rd_clk),
|
||||||
|
.rd_en (rd_en),
|
||||||
|
.rd_addr (rd_addr[AW-1:0]),
|
||||||
|
.wr_clk (wr_clk),
|
||||||
|
.wr_en (wr_en),
|
||||||
|
.wr_addr (wr_addr[AW-1:0]),
|
||||||
|
.wr_wem (wr_wem[DW-1:0]),
|
||||||
|
.wr_din (wr_din[DW-1:0]),
|
||||||
|
.bist_en (bist_en),
|
||||||
|
.bist_we (bist_we),
|
||||||
|
.bist_wem (bist_wem[DW-1:0]),
|
||||||
|
.bist_addr (bist_addr[AW-1:0]),
|
||||||
|
.bist_din (bist_din[DW-1:0]),
|
||||||
|
.bist_dout (bist_dout[DW-1:0]),
|
||||||
|
.shutdown (shutdown),
|
||||||
|
.vss (vss),
|
||||||
|
.vdd (vdd),
|
||||||
|
.vddio (vddio),
|
||||||
|
.memconfig (memconfig[7:0]),
|
||||||
|
.memrepair (memrepair[7:0]));
|
||||||
|
end // block: hard
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule // oh_memory_dp
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,16 +14,19 @@ module oh_mux #( parameter DW = 1, // width of data inputs
|
|||||||
output [DW-1:0] out // output
|
output [DW-1:0] out // output
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [DW-1:0] out;
|
//local variable
|
||||||
|
reg [DW-1:0] mux;
|
||||||
|
|
||||||
integer i;
|
integer i;
|
||||||
always @*
|
always @*
|
||||||
begin
|
begin
|
||||||
out[DW-1:0] = 'b0;
|
mux[DW-1:0] = 'b0;
|
||||||
for(i=0;i<N;i=i+1)
|
for(i=0;i<N;i=i+1)
|
||||||
out[DW-1:0] |= {(DW){sel[i]}} & in[((i+1)*DW-1)-:DW];
|
mux[DW-1:0] = mux[DW-1:0] | {(DW){sel[i]}} & in[((i+1)*DW-1)-:DW];
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assign out[DW-1:0] = mux;
|
||||||
|
|
||||||
endmodule // oh_mux
|
endmodule // oh_mux
|
||||||
|
|
||||||
|
|
@ -27,7 +27,6 @@ module oh_mux4 #(parameter DW = 1 ) // width of mux
|
|||||||
wire error;
|
wire error;
|
||||||
assign error = (sel0 | sel1 | sel2 | sel3) &
|
assign error = (sel0 | sel1 | sel2 | sel3) &
|
||||||
~(sel0 ^ sel1 ^ sel2 ^ sel3);
|
~(sel0 ^ sel1 ^ sel2 ^ sel3);
|
||||||
|
|
||||||
always @ (posedge error)
|
always @ (posedge error)
|
||||||
begin
|
begin
|
||||||
#1 if(error)
|
#1 if(error)
|
@ -14,22 +14,13 @@ module oh_oddr #(parameter DW = 1) // width of data inputs
|
|||||||
);
|
);
|
||||||
|
|
||||||
//regs("sl"=stable low, "sh"=stable high)
|
//regs("sl"=stable low, "sh"=stable high)
|
||||||
reg [DW-1:0] q1_sl;
|
reg [DW-1:0] din2_sh;
|
||||||
reg [DW-1:0] q2_sl;
|
|
||||||
reg [DW-1:0] q2_sh;
|
|
||||||
|
|
||||||
//Generate different logic based on parameters
|
|
||||||
always @ (posedge clk)
|
|
||||||
begin
|
|
||||||
q1_sl[DW-1:0] <= din1[DW-1:0];
|
|
||||||
q2_sl[DW-1:0] <= din2[DW-1:0];
|
|
||||||
end
|
|
||||||
|
|
||||||
always @ (negedge clk)
|
always @ (negedge clk)
|
||||||
q2_sh[DW-1:0] <= q2_sl[DW-1:0];
|
din2_sh[DW-1:0] <= din2[DW-1:0];
|
||||||
|
|
||||||
assign out[DW-1:0] = clk ? q1_sl[DW-1:0] :
|
assign out[DW-1:0] = ~clk ? din1[DW-1:0] :
|
||||||
q2_sh[DW-1:0];
|
din2_sh[DW-1:0];
|
||||||
|
|
||||||
endmodule // oh_oddr
|
endmodule // oh_oddr
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user