1
0
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:
aolofsson 2021-04-26 08:56:16 -04:00
commit 65a13b5067
634 changed files with 2505 additions and 11916 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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
View 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)

View File

@ -0,0 +1,3 @@
7766554433221101 //first line
FFEEDDCCBBEE9901 //second line
0000000000000000 //end of stimulus [0]=0

View File

@ -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
View 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
View 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
View 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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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
View 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

View File

@ -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
View 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

View File

@ -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

View File

@ -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

View File

@ -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
View 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
View 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
View 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

View File

@ -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

View File

@ -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
View 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
View 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

View File

@ -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

View File

@ -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)

View File

@ -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