mirror of
https://github.com/aolofsson/oh.git
synced 2025-01-30 02:32:53 +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)
|
||||
* [Wavedrom](http://wavedrom.com/editor.html)
|
||||
* [FuseSoC](https://github.com/olofk/fusesoc)
|
||||
* [OpenROAD](https://github.com/The-OpenROAD-Project/OpenROAD)
|
||||
|
||||
|
||||
## 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 ../../emesh/dv
|
||||
-y ../../memory/dv
|
||||
@ -29,3 +30,4 @@
|
||||
+incdir+../../gpio/hdl
|
||||
+incdir+../../spi/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) #
|
||||
//#############################################################################
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -11,19 +11,13 @@ module oh_buffer #(parameter N = 1, // number of inputs
|
||||
output [N-1:0] out // output
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC;
|
||||
|
||||
generate
|
||||
if(ASIC)
|
||||
begin : asic
|
||||
`ifdef CFG_ASIC
|
||||
asic_buf #(.SIZE(SIZE)) ibuf [N-1:0] (.in(in[N-1:0]),
|
||||
.out(out[N-1:0]));
|
||||
end
|
||||
else
|
||||
begin : generic
|
||||
`else
|
||||
assign out[N-1:0] = in[N-1:0];
|
||||
end
|
||||
endgenerate
|
||||
`endif
|
||||
|
||||
endmodule // oh_buffer
|
||||
|
||||
|
@ -7,23 +7,17 @@
|
||||
|
||||
module oh_clockgate (
|
||||
input clk, // clock input
|
||||
input te, // test enable enable
|
||||
input te, // test enable
|
||||
input en, // enable (from positive edge FF)
|
||||
output eclk // enabled clock output
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC; // use ASIC lib
|
||||
|
||||
generate
|
||||
if(ASIC)
|
||||
begin : asic
|
||||
`ifdef CFG_ASIC
|
||||
asic_icg icg (.en(en),
|
||||
.te(te),
|
||||
.clk(clk),
|
||||
.eclk(eclk));
|
||||
end
|
||||
else
|
||||
begin : generic
|
||||
`else
|
||||
wire en_sh;
|
||||
wire en_sl;
|
||||
//Stable low/valid rising edge enable
|
||||
@ -34,8 +28,7 @@ module oh_clockgate (
|
||||
.clk (clk));
|
||||
|
||||
assign eclk = clk & en_sh;
|
||||
end
|
||||
endgenerate
|
||||
`endif // !`ifdef CFG_ASIC
|
||||
|
||||
endmodule // oh_clockgate
|
||||
|
@ -12,26 +12,25 @@ module oh_clockmux #(parameter N = 1) // number of clock inputs
|
||||
output clkout
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC;
|
||||
|
||||
`ifdef CFG_ASIC
|
||||
generate
|
||||
if(ASIC& (N==2))
|
||||
if((N==2))
|
||||
begin : asic
|
||||
asic_clockmux2 imux (.clkin(clkin[N-1:0]),
|
||||
.en(en[N-1:0]),
|
||||
.clkout(clkout));
|
||||
end
|
||||
else if(ASIC & (N==4))
|
||||
else if((N==4))
|
||||
begin : asic
|
||||
asic_clockmux4 imux (.clkin(clkin[N-1:0]),
|
||||
.en(en[N-1:0]),
|
||||
.clkout(clkout));
|
||||
end
|
||||
else
|
||||
begin : generic
|
||||
assign clkout = |(clkin[N-1:0] & en[N-1:0]);
|
||||
end
|
||||
endgenerate
|
||||
`else // !`ifdef CFG_ASIC
|
||||
assign clkout = |(clkin[N-1:0] & en[N-1:0]);
|
||||
`endif
|
||||
|
||||
endmodule // oh_clockmux
|
||||
|
||||
|
@ -11,10 +11,9 @@ module oh_clockor #(parameter N = 1) // number of clock inputs
|
||||
output clkout
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC;
|
||||
|
||||
`ifdef CFG_ASIC
|
||||
generate
|
||||
if(ASIC & (N==4))
|
||||
if((N==4))
|
||||
begin : asic
|
||||
asic_clockor4 ior (/*AUTOINST*/
|
||||
// Outputs
|
||||
@ -23,20 +22,19 @@ module oh_clockor #(parameter N = 1) // number of clock inputs
|
||||
.clkin (clkin[3:0]));
|
||||
|
||||
end // block: g0
|
||||
else if(ASIC & (N==2))
|
||||
else if((N==2))
|
||||
begin : asic
|
||||
asic_clockor2 ior (/*AUTOINST*/
|
||||
// Outputs
|
||||
.clkout (clkout),
|
||||
// Inputs
|
||||
.clkin (clkin[1:0]));
|
||||
|
||||
end // block: g0
|
||||
else
|
||||
begin : generic
|
||||
assign clkout = |(clkin[N-1:0]);
|
||||
end
|
||||
endgenerate
|
||||
`else
|
||||
assign clkout = |(clkin[N-1:0]);
|
||||
`endif
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC; // use asic library
|
||||
|
||||
generate
|
||||
if(ASIC)
|
||||
begin : asic
|
||||
asic_csa32 i_csa32[DW-1:0] (.s(s[DW-1:0]),
|
||||
.c(c[DW-1:0]),
|
||||
.in2(in2[DW-1:0]),
|
||||
.in1(in1[DW-1:0]),
|
||||
.in0(in0[DW-1:0]));
|
||||
`ifdef CFG_ASIC
|
||||
genvar i;
|
||||
for (i=0;i<DW;i=i+1)
|
||||
begin
|
||||
asic_csa32 asic_csa32 (.s(s[i]),
|
||||
.c(c[i]),
|
||||
.in2(in2[i]),
|
||||
.in1(in1[i]),
|
||||
.in0(in0[i]));
|
||||
end
|
||||
else
|
||||
begin : generic
|
||||
`else
|
||||
assign s[DW-1:0] = in0[DW-1:0] ^ in1[DW-1:0] ^ in2[DW-1:0];
|
||||
assign c[DW-1:0] = (in0[DW-1:0] & in1[DW-1:0]) |
|
||||
(in1[DW-1:0] & in2[DW-1:0]) |
|
||||
(in2[DW-1:0] & in0[DW-1:0] );
|
||||
end
|
||||
endgenerate
|
||||
`endif // !`ifdef CFG_ASIC
|
||||
|
||||
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 #
|
||||
//# License: MIT (see LICENSE file in OH! repository) #
|
||||
//#############################################################################
|
||||
//
|
||||
|
||||
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
|
||||
@ -15,14 +16,14 @@ module oh_datagate #(parameter DW = 32, // width of data inputs
|
||||
output [DW-1:0] dout // data output
|
||||
);
|
||||
|
||||
|
||||
reg [PS-1:0] enable_pipe;
|
||||
reg [N-1:0] enable_pipe;
|
||||
wire enable;
|
||||
|
||||
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];
|
||||
|
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
|
||||
|
||||
|
||||
|
@ -15,29 +15,22 @@ module oh_dsync #(parameter PS = 2, // number of sync stages
|
||||
output dout // synchronized data
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC; // use asic library
|
||||
|
||||
generate
|
||||
if(ASIC)
|
||||
begin : g0
|
||||
`ifdef CFG_ASIC
|
||||
asic_dsync asic_dsync (.clk(clk),
|
||||
.nreset(nreset),
|
||||
.din(din),
|
||||
.dout(dout));
|
||||
end
|
||||
else
|
||||
begin : g0
|
||||
`else
|
||||
reg [PS:0] sync_pipe;
|
||||
always @ (posedge clk or negedge nreset)
|
||||
if(!nreset)
|
||||
sync_pipe[PS:0] <= 1'b0;
|
||||
sync_pipe[PS:0] <= 'b0;
|
||||
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
|
||||
`endif // !`ifdef CFG_ASIC
|
||||
|
||||
endmodule // oh_dsync
|
||||
|
@ -13,12 +13,15 @@ module oh_fifo_async # (parameter DW = 104, // FIFO width
|
||||
)
|
||||
(
|
||||
input nreset, // async reset
|
||||
//Write Side
|
||||
input wr_clk, // write clock
|
||||
input wr_en, // write fifo
|
||||
input [DW-1:0] din, // data to write
|
||||
//Read Side
|
||||
input rd_clk, // read clock
|
||||
input rd_en, // read fifo
|
||||
output [DW-1:0] dout, // output data (next cycle)
|
||||
//Status
|
||||
output full, // fifo is full
|
||||
output prog_full, // fifo reaches full threshold
|
||||
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
|
||||
|
||||
generate
|
||||
if(TARGET=="GENERIC") begin : basic
|
||||
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 (TARGET=="XILINX") begin : xilinx
|
||||
if((DW==104) & (DEPTH==32))
|
||||
begin : g104x32
|
||||
fifo_async_104x32
|
||||
@ -86,7 +51,27 @@ module oh_fifo_async # (parameter DW = 104, // FIFO width
|
||||
.din (din[DW-1:0]),
|
||||
.rd_en (rd_en));
|
||||
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
|
||||
|
||||
endmodule // oh_fifo_async
|
@ -10,15 +10,18 @@ module oh_fifo_cdc # (parameter DW = 104, //FIFO width
|
||||
parameter TARGET = "GENERIC" //XILINX,ALTERA,GENERIC
|
||||
)
|
||||
(
|
||||
input nreset, // shared domain async active low reset
|
||||
input nreset, // async active low reset
|
||||
//Write Side
|
||||
input clk_in, // write clock
|
||||
input access_in, // write access
|
||||
input valid_in, // write valid
|
||||
input [DW-1:0] packet_in, // write packet
|
||||
output wait_out, // write pushback
|
||||
output ready_out, // write pushback
|
||||
//Read Side
|
||||
input clk_out, //read clock
|
||||
output reg access_out, //read access
|
||||
output reg valid_out, //read valid
|
||||
output [DW-1:0] packet_out, //read packet
|
||||
input wait_in, // read pushback
|
||||
input ready_in, // read pushback
|
||||
//Status
|
||||
output prog_full, // fifo is half full
|
||||
output full, // fifo is full
|
||||
output empty // fifo is empty
|
||||
@ -27,7 +30,6 @@ module oh_fifo_cdc # (parameter DW = 104, //FIFO width
|
||||
// local wires
|
||||
wire wr_en;
|
||||
wire rd_en;
|
||||
wire io_nreset;
|
||||
|
||||
// parametric async fifo
|
||||
oh_fifo_async #(.TARGET(TARGET),
|
||||
@ -46,21 +48,21 @@ module oh_fifo_cdc # (parameter DW = 104, //FIFO width
|
||||
.rd_en (rd_en));
|
||||
|
||||
// FIFO control logic
|
||||
assign wr_en = access_in;
|
||||
assign rd_en = ~empty & ~wait_in;
|
||||
assign wait_out = prog_full; //wait_out should stall access_in signal
|
||||
assign wr_en = valid_in;
|
||||
assign rd_en = ~empty & ready_in;
|
||||
assign ready_out = ~prog_full;
|
||||
|
||||
// pipeline access_out signal
|
||||
always @ (posedge clk_out or negedge io_nreset)
|
||||
if(!io_nreset)
|
||||
access_out <= 1'b0;
|
||||
else if(~wait_in)
|
||||
access_out <= rd_en;
|
||||
|
||||
// be safe, synchronize reset with clk_out
|
||||
oh_rsync sync_reset(.nrst_out (io_nreset),
|
||||
//async asser, sync deassert of reset
|
||||
oh_rsync sync_reset(.nrst_out (nreset_out),
|
||||
.clk (clk_out),
|
||||
.nrst_in (nreset));
|
||||
|
||||
//align valid signal with FIFO read delay
|
||||
always @ (posedge clk_out or negedge nreset_out)
|
||||
if(!nreset_out)
|
||||
valid_out <= 1'b0;
|
||||
else if(ready_in)
|
||||
valid_out <= rd_en;
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC; // use ASIC lib
|
||||
|
||||
generate
|
||||
if(ASIC)
|
||||
begin : g0
|
||||
`ifdef CFG_ASIC
|
||||
asic_lat0 ilat [DW-1:0] (.clk(clk),
|
||||
.in(in[DW-1:0]),
|
||||
.out(out[DW-1:0]));
|
||||
end
|
||||
else
|
||||
begin : g0
|
||||
`else
|
||||
reg [DW-1:0] out_reg;
|
||||
always @ (clk or in)
|
||||
always_latch
|
||||
if (!clk)
|
||||
out_reg[DW-1:0] <= in[DW-1:0];
|
||||
assign out[DW-1:0] = out_reg[DW-1:0];
|
||||
end // else: !if(ASIC)
|
||||
endgenerate
|
||||
`endif
|
||||
|
||||
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)
|
||||
);
|
||||
|
||||
localparam ASIC = `CFG_ASIC; // use ASIC lib
|
||||
|
||||
generate
|
||||
if(ASIC)
|
||||
begin : g0
|
||||
`ifdef CFG_ASIC
|
||||
asic_lat1 i_lat [DW-1:0] (.clk(clk),
|
||||
.in(in[DW-1:0]),
|
||||
.out(out[DW-1:0]));
|
||||
end
|
||||
else
|
||||
begin : g0
|
||||
`else
|
||||
reg [DW-1:0] out_reg;
|
||||
always @ (clk or in)
|
||||
always_latch
|
||||
if (clk)
|
||||
out_reg[DW-1:0] <= in[DW-1:0];
|
||||
assign out[DW-1:0] = out_reg[DW-1:0];
|
||||
end
|
||||
endgenerate
|
||||
`endif
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
reg [DW-1:0] out;
|
||||
//local variable
|
||||
reg [DW-1:0] mux;
|
||||
|
||||
integer i;
|
||||
always @*
|
||||
begin
|
||||
out[DW-1:0] = 'b0;
|
||||
mux[DW-1:0] = 'b0;
|
||||
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
|
||||
|
||||
assign out[DW-1:0] = mux;
|
||||
|
||||
endmodule // oh_mux
|
||||
|
||||
|
@ -27,7 +27,6 @@ module oh_mux4 #(parameter DW = 1 ) // width of mux
|
||||
wire error;
|
||||
assign error = (sel0 | sel1 | sel2 | sel3) &
|
||||
~(sel0 ^ sel1 ^ sel2 ^ sel3);
|
||||
|
||||
always @ (posedge error)
|
||||
begin
|
||||
#1 if(error)
|
@ -14,22 +14,13 @@ module oh_oddr #(parameter DW = 1) // width of data inputs
|
||||
);
|
||||
|
||||
//regs("sl"=stable low, "sh"=stable high)
|
||||
reg [DW-1:0] q1_sl;
|
||||
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
|
||||
reg [DW-1:0] din2_sh;
|
||||
|
||||
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] :
|
||||
q2_sh[DW-1:0];
|
||||
assign out[DW-1:0] = ~clk ? din1[DW-1:0] :
|
||||
din2_sh[DW-1:0];
|
||||
|
||||
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