mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-08 15:13:24 +00:00
Merge pull request #4976 from Logikable/main
Support array ranges for identifiers in the Liberty parser.
This commit is contained in:
commit
a5e8f52ce5
15 changed files with 156 additions and 144 deletions
1
Makefile
1
Makefile
|
@ -890,6 +890,7 @@ SH_TEST_DIRS += tests/rpc
|
||||||
SH_TEST_DIRS += tests/memfile
|
SH_TEST_DIRS += tests/memfile
|
||||||
SH_TEST_DIRS += tests/fmt
|
SH_TEST_DIRS += tests/fmt
|
||||||
SH_TEST_DIRS += tests/cxxrtl
|
SH_TEST_DIRS += tests/cxxrtl
|
||||||
|
SH_TEST_DIRS += tests/liberty
|
||||||
ifeq ($(ENABLE_FUNCTIONAL_TESTS),1)
|
ifeq ($(ENABLE_FUNCTIONAL_TESTS),1)
|
||||||
SH_TEST_DIRS += tests/functional
|
SH_TEST_DIRS += tests/functional
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -417,24 +417,8 @@ int LibertyParser::lexer(std::string &str)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
LibertyAst *LibertyParser::parse()
|
void LibertyParser::report_unexpected_token(int tok)
|
||||||
{
|
{
|
||||||
std::string str;
|
|
||||||
|
|
||||||
int tok = lexer(str);
|
|
||||||
|
|
||||||
// there are liberty files in the wild that
|
|
||||||
// have superfluous ';' at the end of
|
|
||||||
// a { ... }. We simply ignore a ';' here.
|
|
||||||
// and get to the next statement.
|
|
||||||
|
|
||||||
while ((tok == 'n') || (tok == ';'))
|
|
||||||
tok = lexer(str);
|
|
||||||
|
|
||||||
if (tok == '}' || tok < 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (tok != 'v') {
|
|
||||||
std::string eReport;
|
std::string eReport;
|
||||||
switch(tok)
|
switch(tok)
|
||||||
{
|
{
|
||||||
|
@ -453,60 +437,16 @@ LibertyAst *LibertyParser::parse()
|
||||||
error(eReport);
|
error(eReport);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error();
|
eReport = "Unexpected token: ";
|
||||||
}
|
eReport += static_cast<char>(tok);
|
||||||
|
error(eReport);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LibertyAst *ast = new LibertyAst;
|
// FIXME: the AST needs to be extended to store
|
||||||
ast->id = str;
|
// these vector ranges.
|
||||||
|
void LibertyParser::parse_vector_range(int tok)
|
||||||
while (1)
|
{
|
||||||
{
|
|
||||||
tok = lexer(str);
|
|
||||||
|
|
||||||
// allow both ';' and new lines to
|
|
||||||
// terminate a statement.
|
|
||||||
if ((tok == ';') || (tok == 'n'))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (tok == ':' && ast->value.empty()) {
|
|
||||||
tok = lexer(ast->value);
|
|
||||||
if (tok == 'v') {
|
|
||||||
tok = lexer(str);
|
|
||||||
}
|
|
||||||
while (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '!') {
|
|
||||||
ast->value += tok;
|
|
||||||
tok = lexer(str);
|
|
||||||
if (tok != 'v')
|
|
||||||
error();
|
|
||||||
ast->value += str;
|
|
||||||
tok = lexer(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
// In a liberty file, all key : value pairs should end in ';'
|
|
||||||
// However, there are some liberty files in the wild that
|
|
||||||
// just have a newline. We'll be kind and accept a newline
|
|
||||||
// instead of the ';' too..
|
|
||||||
if ((tok == ';') || (tok == 'n'))
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
error();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tok == '(') {
|
|
||||||
while (1) {
|
|
||||||
std::string arg;
|
|
||||||
tok = lexer(arg);
|
|
||||||
if (tok == ',')
|
|
||||||
continue;
|
|
||||||
if (tok == ')')
|
|
||||||
break;
|
|
||||||
|
|
||||||
// FIXME: the AST needs to be extended to store
|
|
||||||
// these vector ranges.
|
|
||||||
if (tok == '[')
|
|
||||||
{
|
|
||||||
// parse vector range [A] or [A:B]
|
// parse vector range [A] or [A:B]
|
||||||
std::string arg;
|
std::string arg;
|
||||||
tok = lexer(arg);
|
tok = lexer(arg);
|
||||||
|
@ -542,28 +482,88 @@ LibertyAst *LibertyParser::parse()
|
||||||
{
|
{
|
||||||
error("Expected ']' on array range.");
|
error("Expected ']' on array range.");
|
||||||
}
|
}
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
LibertyAst *LibertyParser::parse()
|
||||||
|
{
|
||||||
|
std::string str;
|
||||||
|
|
||||||
|
int tok = lexer(str);
|
||||||
|
|
||||||
|
// there are liberty files in the wild that
|
||||||
|
// have superfluous ';' at the end of
|
||||||
|
// a { ... }. We simply ignore a ';' here.
|
||||||
|
// and get to the next statement.
|
||||||
|
|
||||||
|
while ((tok == 'n') || (tok == ';'))
|
||||||
|
tok = lexer(str);
|
||||||
|
|
||||||
|
if (tok == '}' || tok < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (tok != 'v') {
|
if (tok != 'v') {
|
||||||
std::string eReport;
|
report_unexpected_token(tok);
|
||||||
switch(tok)
|
|
||||||
{
|
|
||||||
case 'n':
|
|
||||||
continue;
|
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
case '}':
|
|
||||||
case '{':
|
|
||||||
case '\"':
|
|
||||||
case ':':
|
|
||||||
eReport = "Unexpected '";
|
|
||||||
eReport += static_cast<char>(tok);
|
|
||||||
eReport += "'.";
|
|
||||||
error(eReport);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
error();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LibertyAst *ast = new LibertyAst;
|
||||||
|
ast->id = str;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
tok = lexer(str);
|
||||||
|
|
||||||
|
// allow both ';' and new lines to
|
||||||
|
// terminate a statement.
|
||||||
|
if ((tok == ';') || (tok == 'n'))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (tok == ':' && ast->value.empty()) {
|
||||||
|
tok = lexer(ast->value);
|
||||||
|
if (tok == 'v') {
|
||||||
|
tok = lexer(str);
|
||||||
|
if (tok == '[') {
|
||||||
|
parse_vector_range(tok);
|
||||||
|
tok = lexer(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (tok == '+' || tok == '-' || tok == '*' || tok == '/' || tok == '!') {
|
||||||
|
ast->value += tok;
|
||||||
|
tok = lexer(str);
|
||||||
|
if (tok != 'v')
|
||||||
|
error();
|
||||||
|
ast->value += str;
|
||||||
|
tok = lexer(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In a liberty file, all key : value pairs should end in ';'
|
||||||
|
// However, there are some liberty files in the wild that
|
||||||
|
// just have a newline. We'll be kind and accept a newline
|
||||||
|
// instead of the ';' too..
|
||||||
|
if ((tok == ';') || (tok == 'n'))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
error();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok == '(') {
|
||||||
|
while (1) {
|
||||||
|
std::string arg;
|
||||||
|
tok = lexer(arg);
|
||||||
|
if (tok == ',')
|
||||||
|
continue;
|
||||||
|
if (tok == ')')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (tok == '[')
|
||||||
|
{
|
||||||
|
parse_vector_range(tok);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (tok == 'n')
|
||||||
|
continue;
|
||||||
|
if (tok != 'v') {
|
||||||
|
report_unexpected_token(tok);
|
||||||
}
|
}
|
||||||
ast->args.push_back(arg);
|
ast->args.push_back(arg);
|
||||||
}
|
}
|
||||||
|
@ -580,7 +580,7 @@ LibertyAst *LibertyParser::parse()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
error();
|
report_unexpected_token(tok);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ast;
|
return ast;
|
||||||
|
|
|
@ -163,6 +163,8 @@ namespace Yosys
|
||||||
*/
|
*/
|
||||||
int lexer(std::string &str);
|
int lexer(std::string &str);
|
||||||
|
|
||||||
|
void report_unexpected_token(int tok);
|
||||||
|
void parse_vector_range(int tok);
|
||||||
LibertyAst *parse();
|
LibertyAst *parse();
|
||||||
void error() const;
|
void error() const;
|
||||||
void error(const std::string &str) const;
|
void error(const std::string &str) const;
|
||||||
|
|
|
@ -9,7 +9,7 @@ library(ls05_stdcells) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : !(B&!A|!B&A) ;
|
function : "!(B&!A|!B&A)" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,5 +2,5 @@ module XNOR2X1 (B, A, Y);
|
||||||
input B;
|
input B;
|
||||||
input A;
|
input A;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = !(B&!A|!B&A); // !(B&!A|!B&A)
|
assign Y = !(B&!A|!B&A); // "!(B&!A|!B&A)"
|
||||||
endmodule
|
endmodule
|
||||||
|
|
6
tests/liberty/idranges.lib
Normal file
6
tests/liberty/idranges.lib
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
library("foobar") {
|
||||||
|
pin("foo") {
|
||||||
|
bar : baz[0] ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
2
tests/liberty/idranges.lib.filtered.ok
Normal file
2
tests/liberty/idranges.lib.filtered.ok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
library("foobar") {
|
||||||
|
}
|
0
tests/liberty/idranges.lib.verilogsim.ok
Normal file
0
tests/liberty/idranges.lib.verilogsim.ok
Normal file
|
@ -6,7 +6,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : A' ;
|
function : "A'" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(tri_inv) {
|
cell(tri_inv) {
|
||||||
|
@ -19,7 +19,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Z) {
|
pin(Z) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : A' ;
|
function : "A'" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(buffer) {
|
cell(buffer) {
|
||||||
|
@ -29,7 +29,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : A ;
|
function : "A" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(nand2) {
|
cell(nand2) {
|
||||||
|
@ -42,7 +42,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : (A * B)' ;
|
function : "(A * B)'" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(nor2) {
|
cell(nor2) {
|
||||||
|
@ -55,7 +55,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : (A + B)' ;
|
function : "(A + B)'" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(xor2) {
|
cell(xor2) {
|
||||||
|
@ -68,7 +68,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : (A *B') + (A' * B) ;
|
function : "(A *B') + (A' * B)" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(imux2) {
|
cell(imux2) {
|
||||||
|
@ -84,16 +84,16 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : ( (A * S) + (B * S') )' ;
|
function : "( (A * S) + (B * S') )'" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(dff) {
|
cell(dff) {
|
||||||
area : 6 ;
|
area : 6 ;
|
||||||
ff(IQ, IQN) {
|
ff("IQ", "IQN") {
|
||||||
next_state : D ;
|
next_state : "D" ;
|
||||||
clocked_on : CLK ;
|
clocked_on : "CLK" ;
|
||||||
clear : RESET ;
|
clear : "RESET" ;
|
||||||
preset : PRESET ;
|
preset : "PRESET" ;
|
||||||
clear_preset_var1 : L ;
|
clear_preset_var1 : L ;
|
||||||
clear_preset_var2 : L ;
|
clear_preset_var2 : L ;
|
||||||
}
|
}
|
||||||
|
@ -111,18 +111,18 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Q) {
|
pin(Q) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : IQ ;
|
function : "IQ" ;
|
||||||
}
|
}
|
||||||
pin(QN) {
|
pin(QN) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : IQN ;
|
function : "IQN" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(latch) {
|
cell(latch) {
|
||||||
area : 5 ;
|
area : 5 ;
|
||||||
latch(IQ, IQN) {
|
latch("IQ", "IQN") {
|
||||||
enable : G ;
|
enable : "G" ;
|
||||||
data_in : D ;
|
data_in : "D" ;
|
||||||
}
|
}
|
||||||
pin(D) {
|
pin(D) {
|
||||||
direction : input ;
|
direction : input ;
|
||||||
|
@ -132,11 +132,11 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Q) {
|
pin(Q) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : IQ ;
|
function : "IQ" ;
|
||||||
}
|
}
|
||||||
pin(QN) {
|
pin(QN) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : IQN ;
|
function : "IQN" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(aoi211) {
|
cell(aoi211) {
|
||||||
|
@ -152,7 +152,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : ((A * B) + C)' ;
|
function : "((A * B) + C)'" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(oai211) {
|
cell(oai211) {
|
||||||
|
@ -168,7 +168,7 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : ((A + B) * C)' ;
|
function : "((A + B) * C)'" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(halfadder) {
|
cell(halfadder) {
|
||||||
|
@ -181,11 +181,11 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(C) {
|
pin(C) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : (A * B) ;
|
function : "(A * B)" ;
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : (A *B') + (A' * B) ;
|
function : "(A *B') + (A' * B)" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cell(fulladder) {
|
cell(fulladder) {
|
||||||
|
@ -201,11 +201,11 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(CO) {
|
pin(CO) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : (((A * B)+(B * CI))+(CI * A)) ;
|
function : "(((A * B)+(B * CI))+(CI * A))" ;
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : ((A^B)^CI) ;
|
function : "((A^B)^CI)" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,86 +1,86 @@
|
||||||
module inv (A, Y);
|
module inv (A, Y);
|
||||||
input A;
|
input A;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ~A; // A'
|
assign Y = ~A; // "A'"
|
||||||
endmodule
|
endmodule
|
||||||
module tri_inv (A, S, Z);
|
module tri_inv (A, S, Z);
|
||||||
input A;
|
input A;
|
||||||
input S;
|
input S;
|
||||||
output Z;
|
output Z;
|
||||||
assign Z = ~A; // A'
|
assign Z = ~A; // "A'"
|
||||||
endmodule
|
endmodule
|
||||||
module buffer (A, Y);
|
module buffer (A, Y);
|
||||||
input A;
|
input A;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = A; // A
|
assign Y = A; // "A"
|
||||||
endmodule
|
endmodule
|
||||||
module nand2 (A, B, Y);
|
module nand2 (A, B, Y);
|
||||||
input A;
|
input A;
|
||||||
input B;
|
input B;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ~(A&B); // (A * B)'
|
assign Y = ~(A&B); // "(A * B)'"
|
||||||
endmodule
|
endmodule
|
||||||
module nor2 (A, B, Y);
|
module nor2 (A, B, Y);
|
||||||
input A;
|
input A;
|
||||||
input B;
|
input B;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ~(A|B); // (A + B)'
|
assign Y = ~(A|B); // "(A + B)'"
|
||||||
endmodule
|
endmodule
|
||||||
module xor2 (A, B, Y);
|
module xor2 (A, B, Y);
|
||||||
input A;
|
input A;
|
||||||
input B;
|
input B;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = (A&~B)|(~A&B); // (A *B') + (A' * B)
|
assign Y = (A&~B)|(~A&B); // "(A *B') + (A' * B)"
|
||||||
endmodule
|
endmodule
|
||||||
module imux2 (A, B, S, Y);
|
module imux2 (A, B, S, Y);
|
||||||
input A;
|
input A;
|
||||||
input B;
|
input B;
|
||||||
input S;
|
input S;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ~(&(A&S)|(B&~S)&); // ( (A * S) + (B * S') )'
|
assign Y = ~(&(A&S)|(B&~S)&); // "( (A * S) + (B * S') )'"
|
||||||
endmodule
|
endmodule
|
||||||
module dff (D, CLK, RESET, PRESET, Q, QN);
|
module dff (D, CLK, RESET, PRESET, Q, QN);
|
||||||
reg IQ, IQN;
|
reg "IQ", "IQN";
|
||||||
input D;
|
input D;
|
||||||
input CLK;
|
input CLK;
|
||||||
input RESET;
|
input RESET;
|
||||||
input PRESET;
|
input PRESET;
|
||||||
output Q;
|
output Q;
|
||||||
assign Q = IQ; // IQ
|
assign Q = IQ; // "IQ"
|
||||||
output QN;
|
output QN;
|
||||||
assign QN = IQN; // IQN
|
assign QN = IQN; // "IQN"
|
||||||
always @(posedge CLK, posedge RESET, posedge PRESET) begin
|
always @(posedge CLK, posedge RESET, posedge PRESET) begin
|
||||||
if ((RESET) && (PRESET)) begin
|
if ((RESET) && (PRESET)) begin
|
||||||
IQ <= 0;
|
"IQ" <= 0;
|
||||||
IQN <= 0;
|
"IQN" <= 0;
|
||||||
end
|
end
|
||||||
else if (RESET) begin
|
else if (RESET) begin
|
||||||
IQ <= 0;
|
"IQ" <= 0;
|
||||||
IQN <= 1;
|
"IQN" <= 1;
|
||||||
end
|
end
|
||||||
else if (PRESET) begin
|
else if (PRESET) begin
|
||||||
IQ <= 1;
|
"IQ" <= 1;
|
||||||
IQN <= 0;
|
"IQN" <= 0;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// D
|
// "D"
|
||||||
IQ <= D;
|
"IQ" <= D;
|
||||||
IQN <= ~(D);
|
"IQN" <= ~(D);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
module latch (D, G, Q, QN);
|
module latch (D, G, Q, QN);
|
||||||
reg IQ, IQN;
|
reg "IQ", "IQN";
|
||||||
input D;
|
input D;
|
||||||
input G;
|
input G;
|
||||||
output Q;
|
output Q;
|
||||||
assign Q = IQ; // IQ
|
assign Q = IQ; // "IQ"
|
||||||
output QN;
|
output QN;
|
||||||
assign QN = IQN; // IQN
|
assign QN = IQN; // "IQN"
|
||||||
always @* begin
|
always @* begin
|
||||||
if (G) begin
|
if (G) begin
|
||||||
IQ <= D;
|
"IQ" <= D;
|
||||||
IQN <= ~(D);
|
"IQN" <= ~(D);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -89,29 +89,29 @@ module aoi211 (A, B, C, Y);
|
||||||
input B;
|
input B;
|
||||||
input C;
|
input C;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ~((A&B)|C); // ((A * B) + C)'
|
assign Y = ~((A&B)|C); // "((A * B) + C)'"
|
||||||
endmodule
|
endmodule
|
||||||
module oai211 (A, B, C, Y);
|
module oai211 (A, B, C, Y);
|
||||||
input A;
|
input A;
|
||||||
input B;
|
input B;
|
||||||
input C;
|
input C;
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ~((A|B)&C); // ((A + B) * C)'
|
assign Y = ~((A|B)&C); // "((A + B) * C)'"
|
||||||
endmodule
|
endmodule
|
||||||
module halfadder (A, B, C, Y);
|
module halfadder (A, B, C, Y);
|
||||||
input A;
|
input A;
|
||||||
input B;
|
input B;
|
||||||
output C;
|
output C;
|
||||||
assign C = (A&B); // (A * B)
|
assign C = (A&B); // "(A * B)"
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = (A&~B)|(~A&B); // (A *B') + (A' * B)
|
assign Y = (A&~B)|(~A&B); // "(A *B') + (A' * B)"
|
||||||
endmodule
|
endmodule
|
||||||
module fulladder (A, B, CI, CO, Y);
|
module fulladder (A, B, CI, CO, Y);
|
||||||
input A;
|
input A;
|
||||||
input B;
|
input B;
|
||||||
input CI;
|
input CI;
|
||||||
output CO;
|
output CO;
|
||||||
assign CO = (((A&B)|(B&CI))|(CI&A)); // (((A * B)+(B * CI))+(CI * A))
|
assign CO = (((A&B)|(B&CI))|(CI&A)); // "(((A * B)+(B * CI))+(CI * A))"
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ((A^B)^CI); // ((A^B)^CI)
|
assign Y = ((A^B)^CI); // "((A^B)^CI)"
|
||||||
endmodule
|
endmodule
|
||||||
|
|
|
@ -7,9 +7,10 @@ for x in *.lib; do
|
||||||
../../yosys-filterlib - $x 2>/dev/null > $x.filtered
|
../../yosys-filterlib - $x 2>/dev/null > $x.filtered
|
||||||
../../yosys-filterlib -verilogsim $x > $x.verilogsim
|
../../yosys-filterlib -verilogsim $x > $x.verilogsim
|
||||||
diff $x.filtered $x.filtered.ok && diff $x.verilogsim $x.verilogsim.ok
|
diff $x.filtered $x.filtered.ok && diff $x.verilogsim $x.verilogsim.ok
|
||||||
done
|
done || exit 1
|
||||||
|
|
||||||
for x in *.ys; do
|
for x in *.ys; do
|
||||||
echo "Running $x.."
|
echo "Running $x.."
|
||||||
../../yosys -q -s $x -l ${x%.ys}.log
|
../../yosys -q -s $x -l ${x%.ys}.log
|
||||||
done
|
done || exit 1
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ library(supergate) {
|
||||||
clock : true ;
|
clock : true ;
|
||||||
}
|
}
|
||||||
ff(IQ, IQN) {
|
ff(IQ, IQN) {
|
||||||
clocked_on : CK ;
|
clocked_on : "CK" ;
|
||||||
next_state : D ;
|
next_state : "D" ;
|
||||||
}
|
}
|
||||||
pin(Q) {
|
pin(Q) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
|
|
|
@ -4,7 +4,7 @@ module DFF (D, CK, Q);
|
||||||
input CK;
|
input CK;
|
||||||
output Q;
|
output Q;
|
||||||
always @(posedge CK) begin
|
always @(posedge CK) begin
|
||||||
// D
|
// "D"
|
||||||
IQ <= D;
|
IQ <= D;
|
||||||
IQN <= ~(D);
|
IQN <= ~(D);
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,11 +12,11 @@ library(supergate) {
|
||||||
}
|
}
|
||||||
pin(CO) {
|
pin(CO) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : (((A * B)+(B * CI))+(CI * A)) ;
|
function : "(((A * B)+(B * CI))+(CI * A))" ;
|
||||||
}
|
}
|
||||||
pin(Y) {
|
pin(Y) {
|
||||||
direction : output ;
|
direction : output ;
|
||||||
function : ((A^B)^CI) ;
|
function : "((A^B)^CI)" ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ module fulladder (A, B, CI, CO, Y);
|
||||||
input B;
|
input B;
|
||||||
input CI;
|
input CI;
|
||||||
output CO;
|
output CO;
|
||||||
assign CO = (((A&B)|(B&CI))|(CI&A)); // (((A * B)+(B * CI))+(CI * A))
|
assign CO = (((A&B)|(B&CI))|(CI&A)); // "(((A * B)+(B * CI))+(CI * A))"
|
||||||
output Y;
|
output Y;
|
||||||
assign Y = ((A^B)^CI); // ((A^B)^CI)
|
assign Y = ((A^B)^CI); // "((A^B)^CI)"
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue