@@ -0,0 +1,234 @@ | |||
`timescale 1 ns / 1 ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: AXI4_STREAM_MASTER_INTERFACE | |||
// Module Name: DOUT_M_AXIS | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: AXI4 Stream Master Interface is used to stream out output data from | |||
// the polar Encoder. | |||
// | |||
//////////////////////////////////////////////////////////////////////////////////// | |||
module DOUT_M_AXIS # | |||
( | |||
// Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_TDATA_WIDTH. | |||
parameter integer C_M_AXIS_TDATA_WIDTH = 32, | |||
parameter integer C_S_AXIS_TDATA_WIDTH = 512, | |||
parameter integer DEPTH = 16, | |||
// Start count is the numeber of clock cycles the master will wait before initiating/issuing any transaction. | |||
parameter integer C_M_START_COUNT = 2 | |||
) | |||
( | |||
// Global ports | |||
input logic M_AXIS_ACLK, | |||
// | |||
input logic M_AXIS_ARESETN, | |||
// Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. | |||
output logic M_AXIS_TVALID, | |||
// TDATA is the primary payload that is used to provide the data that is passing across the interface from the master. | |||
output logic [C_M_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA, | |||
// TLAST indicates the boundary of a packet. | |||
output logic M_AXIS_TLAST, | |||
// TREADY indicates that the slave can accept a transfer in the current cycle. | |||
input logic M_AXIS_TREADY, | |||
// Input from PBCH Encoder Core of Width 864 bits | |||
input logic [C_S_AXIS_TDATA_WIDTH-1:0]S_AXIS_TDATA, | |||
// Input from PBCH Encoder Core | |||
input logic DONE | |||
); | |||
//Total number of output data. | |||
// Total number of output data | |||
localparam NUMBER_OF_OUTPUT_WORDS = 27; | |||
// function called clogb2 that returns an integer which has the | |||
// value of the ceiling of the log base 2. | |||
function integer clogb2 (input integer bit_depth); | |||
begin | |||
for(clogb2=0; bit_depth>0; clogb2=clogb2+1) | |||
bit_depth = bit_depth >> 1; | |||
end | |||
endfunction | |||
// WAIT_COUNT_BITS is the width of the wait counter. | |||
localparam integer WAIT_COUNT_BITS = clogb2(C_M_START_COUNT-1); | |||
// bit_num gives the minimum number of bits needed to address 'depth' size of FIFO. | |||
localparam bit_num = clogb2(NUMBER_OF_OUTPUT_WORDS); | |||
// Define the states of state machine | |||
// The control state machine oversees the writing of input streaming data to the FIFO, | |||
// and outputs the streaming data from the FIFO | |||
parameter [1:0] IDLE = 2'b00, // This is the initial/idle state | |||
INIT_COUNTER = 2'b01, // This state initializes the counter, ones | |||
// the counter reaches C_M_START_COUNT count, | |||
// the state machine changes state to INIT_WRITE | |||
SEND_STREAM = 2'b10; // In this state the | |||
// stream data is output through M_AXIS_TDATA | |||
// State variable | |||
logic [1:0] mst_exec_state; | |||
// FIFO read pointer | |||
logic [bit_num-1:0] read_pointer; | |||
// AXI Stream internal signals | |||
//wait counter. The master waits for the user defined number of clock cycles before initiating a transfer. | |||
logic [WAIT_COUNT_BITS-1 : 0] count; | |||
//streaming data valid | |||
logic axis_tvalid; | |||
//streaming data valid delayed by one clock cycle | |||
logic axis_tvalid_delay; | |||
//Last of the streaming data | |||
logic axis_tlast; | |||
//Last of the streaming data delayed by one clock cycle | |||
logic axis_tlast_delay; | |||
//FIFO implementation signals | |||
logic [C_M_AXIS_TDATA_WIDTH-1 : 0] stream_data_out; | |||
logic tx_en; | |||
//The master has issued all the streaming data stored in FIFO | |||
logic tx_done; | |||
(* ram_style="register" *) | |||
logic [C_M_AXIS_TDATA_WIDTH-1:0] slv_reg0 [0:DEPTH-1]; | |||
// I/O Connections assignments | |||
assign M_AXIS_TVALID = axis_tvalid_delay; | |||
assign M_AXIS_TDATA = stream_data_out; | |||
assign M_AXIS_TLAST = axis_tlast_delay; | |||
integer i; | |||
integer byte_index; | |||
always_ff @( posedge M_AXIS_ACLK ) | |||
begin | |||
if (!M_AXIS_ARESETN ) | |||
begin | |||
stream_data_out <= 0; | |||
for(i = 0; i <= DEPTH - 1 ; i = i+1) | |||
slv_reg0[i] <= 0; | |||
end | |||
else | |||
begin | |||
if (DONE) | |||
for ( byte_index = 0; byte_index <= DEPTH - 1; byte_index = byte_index+1 ) | |||
slv_reg0[byte_index] <= S_AXIS_TDATA[(byte_index*C_M_AXIS_TDATA_WIDTH) +: C_M_AXIS_TDATA_WIDTH]; | |||
else if (tx_en) | |||
begin | |||
stream_data_out <= slv_reg0[read_pointer]; | |||
end | |||
end | |||
end | |||
// Control state machine implementation | |||
always_ff @(posedge M_AXIS_ACLK) | |||
begin | |||
// Synchronous reset (active low) | |||
if (!M_AXIS_ARESETN) | |||
begin | |||
mst_exec_state <= IDLE; | |||
count <= 0; | |||
end | |||
else | |||
case (mst_exec_state) | |||
IDLE: | |||
// The slave starts accepting tdata when | |||
// there tvalid is asserted to mark the | |||
// presence of valid streaming data | |||
mst_exec_state <= INIT_COUNTER; | |||
INIT_COUNTER: | |||
// The slave starts accepting tdata when | |||
// there tvalid is asserted to mark the | |||
// presence of valid streaming data | |||
if ( count == C_M_START_COUNT - 1 ) | |||
begin | |||
mst_exec_state <= SEND_STREAM; | |||
end | |||
else | |||
begin | |||
count <= count + 1; | |||
mst_exec_state <= INIT_COUNTER; | |||
end | |||
SEND_STREAM: | |||
// The example design streaming master functionality starts | |||
// when the master drives output tdata from the FIFO and the slave | |||
// has finished storing the S_AXIS_TDATA | |||
if (tx_done) | |||
begin | |||
mst_exec_state <= IDLE; | |||
end | |||
else | |||
begin | |||
mst_exec_state <= SEND_STREAM; | |||
end | |||
endcase | |||
end | |||
//tvalid generation | |||
//axis_tvalid is asserted when the control state machine's state is SEND_STREAM and | |||
//number of output streaming data is less than the NUMBER_OF_OUTPUT_WORDS. | |||
assign axis_tvalid = ((mst_exec_state == SEND_STREAM) && (read_pointer < NUMBER_OF_OUTPUT_WORDS)); | |||
// AXI tlast generation | |||
// axis_tlast is asserted number of output streaming data is NUMBER_OF_OUTPUT_WORDS-1 | |||
// (0 to NUMBER_OF_OUTPUT_WORDS-1) | |||
assign axis_tlast = (read_pointer == NUMBER_OF_OUTPUT_WORDS-1); | |||
// Delay the axis_tvalid and axis_tlast signal by one clock cycle | |||
// to match the latency of M_AXIS_TDATA | |||
always_ff @(posedge M_AXIS_ACLK) | |||
begin | |||
if (!M_AXIS_ARESETN) | |||
begin | |||
axis_tvalid_delay <= 1'b0; | |||
axis_tlast_delay <= 1'b0; | |||
end | |||
else | |||
begin | |||
axis_tvalid_delay <= axis_tvalid; | |||
axis_tlast_delay <= axis_tlast; | |||
end | |||
end | |||
//read_pointer pointer | |||
always_ff@(posedge M_AXIS_ACLK) | |||
begin | |||
if(!M_AXIS_ARESETN) | |||
begin | |||
read_pointer <= 0; | |||
tx_done <= 1'b0; | |||
end | |||
else | |||
if (read_pointer <= NUMBER_OF_OUTPUT_WORDS-1) | |||
begin | |||
if (tx_en) | |||
// read pointer is incremented after every read from the FIFO | |||
// when FIFO read signal is enabled. | |||
begin | |||
read_pointer <= read_pointer + 1; | |||
tx_done <= 1'b0; | |||
end | |||
end | |||
else if (read_pointer == NUMBER_OF_OUTPUT_WORDS) | |||
begin | |||
// tx_done is asserted when NUMBER_OF_OUTPUT_WORDS numbers of streaming data | |||
// has been out. | |||
tx_done <= 1'b1; | |||
if(DONE)read_pointer <= 0; | |||
end | |||
end | |||
//FIFO read enable generation | |||
assign tx_en = M_AXIS_TREADY && axis_tvalid; | |||
endmodule |
@@ -0,0 +1,159 @@ | |||
`timescale 1 ns / 1 ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: AXI4_STREAM_SLAVE_INTERFACE | |||
// Module Name: S_AXIS | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: AXI4 Stream Slave Interface is used to stream input data to the | |||
// polar Encoder. | |||
// | |||
//////////////////////////////////////////////////////////////////////////////////// | |||
module S_AXIS # | |||
( // AXI4Stream sink: Data Width | |||
parameter integer C_S_AXIS_TDATA_WIDTH = 32 | |||
) | |||
( // AXI4Stream sink: Clock | |||
input wire S_AXIS_ACLK, | |||
// AXI4Stream sink: Reset | |||
input wire S_AXIS_ARESETN, | |||
// Ready to accept data in | |||
output wire S_AXIS_TREADY, | |||
// Data out | |||
output [C_S_AXIS_TDATA_WIDTH-1 : 0] M_AXIS_TDATA, | |||
// Data in | |||
input wire [C_S_AXIS_TDATA_WIDTH-1 : 0] S_AXIS_TDATA, | |||
// Indicates boundary of last packet | |||
input wire S_AXIS_TLAST, | |||
// Data is in valid | |||
input wire S_AXIS_TVALID, | |||
input wire tready_in, | |||
output logic read_en | |||
); | |||
// function called clogb2 that returns an integer which has the | |||
// value of the ceiling of the log base 2. | |||
function integer clogb2 (input integer bit_depth); | |||
begin | |||
for(clogb2=0; bit_depth>0; clogb2=clogb2+1) | |||
bit_depth = bit_depth >> 1; | |||
end | |||
endfunction | |||
// Total number of input data. | |||
localparam NUMBER_OF_INPUT_WORDS = 8; | |||
localparam NUMBER_OF_OUTPUT_WORDS = 8; | |||
// bit_num gives the minimum number of bits needed to address 'NUMBER_OF_INPUT_WORDS' size of FIFO. | |||
localparam bit_num = clogb2(NUMBER_OF_INPUT_WORDS-1); | |||
localparam aw = clogb2(C_S_AXIS_TDATA_WIDTH); | |||
// The control state machine oversees the writing of input streaming data to the FIFO, | |||
// and outputs the streaming data from the FIFO | |||
localparam [1:0] IDLE = 2'b00, // This is the initial/idle state | |||
WRITE_FIFO = 2'b01, // In this state FIFO is written with the | |||
// input stream data S_AXIS_TDATA | |||
FIRST_READ = 2'b10, // Read first from FIFO as soon as it writes | |||
READ_FIFO = 2'b11; // Read State | |||
logic axis_tready; | |||
logic [1:0] mst_exec_state; // State variable | |||
logic fifo_wren; // FIFO write enable | |||
logic fifo_full_flag; // FIFO full flag | |||
logic fifo_empty; // FIFO Empty | |||
logic full_n; // FIFO is being written | |||
logic first_read_en; // First Read Enable | |||
logic [5:0] count; | |||
logic tx_en; | |||
// I/O Connections assignments | |||
assign read_en = (tready_in || first_read_en); | |||
assign S_AXIS_TREADY = axis_tready; | |||
// Control state machine implementation | |||
always @(posedge S_AXIS_ACLK) | |||
begin | |||
if (!S_AXIS_ARESETN) | |||
// Synchronous reset (active low) | |||
begin | |||
mst_exec_state <= IDLE; | |||
first_read_en <= 0; | |||
end | |||
else | |||
case (mst_exec_state) | |||
IDLE: begin | |||
// The sink starts accepting tdata when | |||
// there tvalid is asserted to mark the | |||
// presence of valid streaming data | |||
first_read_en <= 0; | |||
if (S_AXIS_TVALID) | |||
begin | |||
mst_exec_state <= WRITE_FIFO; | |||
end | |||
else | |||
begin | |||
mst_exec_state <= IDLE; | |||
end | |||
end | |||
WRITE_FIFO: begin | |||
// When the sink has accepted all the streaming input data, | |||
// the interface swiches functionality to a streaming master | |||
// if (writes_done) | |||
first_read_en <= 0; | |||
if(full_n && count == 1) | |||
mst_exec_state <= FIRST_READ; | |||
else if (fifo_full_flag) | |||
begin | |||
mst_exec_state <= READ_FIFO; | |||
end | |||
else | |||
begin | |||
// The sink accepts and stores tdata | |||
// into FIFO | |||
mst_exec_state <= WRITE_FIFO; | |||
end | |||
end | |||
FIRST_READ: begin | |||
first_read_en <= 1'b1; | |||
if(!fifo_full_flag) | |||
mst_exec_state <= WRITE_FIFO; | |||
else | |||
mst_exec_state <= READ_FIFO; | |||
end | |||
READ_FIFO : begin | |||
first_read_en <= 0; | |||
if(fifo_empty) | |||
mst_exec_state <= IDLE; | |||
else if(!fifo_full_flag) | |||
mst_exec_state <= WRITE_FIFO; | |||
else | |||
mst_exec_state <= READ_FIFO; | |||
end | |||
endcase | |||
end | |||
// AXI Streaming Sink | |||
// | |||
// design sink is always ready to accept the S_AXIS_TDATA until | |||
// the FIFO is not filled with NUMBER_OF_INPUT_WORDS number of input words. | |||
assign axis_tready = ((mst_exec_state == WRITE_FIFO) || (mst_exec_state == READ_FIFO)) && !fifo_full_flag && !S_AXIS_TLAST; | |||
// FIFO write enable generation | |||
assign fifo_wren = S_AXIS_TVALID && axis_tready && !fifo_full_flag && !S_AXIS_TLAST; | |||
fifo #(.dw(C_S_AXIS_TDATA_WIDTH),.aw(aw-1),.n(C_S_AXIS_TDATA_WIDTH))FIFO(.clk(S_AXIS_ACLK),.rst(S_AXIS_ARESETN),.din(S_AXIS_TDATA),.we(fifo_wren),.dout(M_AXIS_TDATA),.re(read_en), | |||
.full(),.empty(),.full_r(fifo_full_flag),.empty_r(fifo_empty),.full_n(full_n), .empty_n(), .full_n_r(), .empty_n_r(),.level(),.count(count)); | |||
//FIFO read enable generation | |||
assign tx_en = axis_tready && S_AXIS_TVALID && tready_in; | |||
endmodule |
@@ -0,0 +1,10 @@ | |||
// For PBCH A = 32 | |||
// For PBCH G = 864 | |||
`define A 32 | |||
`define G 864 | |||
`define PBCH 1 |
@@ -0,0 +1,105 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PVT LTD | |||
// Design Name:PBCH_POLAR_ENCODER_IP | |||
// Module Name: PBCH_POLAR_ENCODER_IP | |||
// Project Name: POLAR IP | |||
// Description: The PBCH_POLAR_ENCODER IP is interfaced with AXI4 Stream DIN | |||
// Slave and DOUT Master interfaces. | |||
////////////////////////////////////////////////////////////////////////////////// | |||
`include "PBCH_Defines.vh" | |||
`define Dx_WIDTH 32 // Dx_WIDTH => DIN_WIDTH / DOUT_WIDTH => AXI4-Stream Interface | |||
`define PDCCH 0 | |||
module PBCH_POLAR_ENCODER_IP( | |||
/**************************************************************/ | |||
// Global Signals | |||
input logic reset_n, // Active Low Reset | |||
input logic core_clk, // Core Clock | |||
/**************************************************************/ | |||
// AXI4 DIN Stream Interface | |||
input logic [`Dx_WIDTH - 1 : 0] s_axis_din_tdata, | |||
input logic s_axis_din_tvalid, | |||
input logic s_axis_din_tlast, | |||
output logic DIN_TREADY, | |||
/**************************************************************/ | |||
// AXI4 DOUT Stream Interface | |||
input logic s_axis_dout_tready, | |||
output logic [`Dx_WIDTH - 1 : 0] DOUT_TDATA, | |||
output logic DOUT_TVALID, | |||
output logic DOUT_TLAST | |||
); | |||
logic [`Dx_WIDTH - 1 : 0] m_axis_din_tdata; | |||
logic [`G - 1 : 0] msg_o; | |||
logic [9:0] global_count; | |||
logic done; | |||
S_AXIS # | |||
(.C_S_AXIS_TDATA_WIDTH(`Dx_WIDTH) | |||
) DIN_STREAM | |||
(.S_AXIS_ACLK(core_clk), | |||
.S_AXIS_ARESETN(reset_n), | |||
.S_AXIS_TREADY(DIN_TREADY), | |||
.M_AXIS_TDATA(m_axis_din_tdata), // Output from Stream | |||
.S_AXIS_TDATA(s_axis_din_tdata), // Input from Stream | |||
.S_AXIS_TLAST(s_axis_din_tlast), | |||
.S_AXIS_TVALID(s_axis_din_tvalid), | |||
.tready_in(done) | |||
); | |||
POLAR_ENCODER | |||
#(.PBCH(`PBCH), // Broadcast Channel enable | |||
.A(`A), // Message width A if no segmentation needed, A'=A/2 if segmentation is needed. | |||
.G(`G) // Length of output | |||
) PBCH | |||
(.clock_i(core_clk), // input clock signal | |||
.reset_ni(reset_n), // input reset | |||
.msg_i(m_axis_din_tdata), // input message bits | |||
.msg_o(msg_o) // output bits | |||
); | |||
always_ff@(posedge core_clk) | |||
if(!reset_n) | |||
global_count <= 0; | |||
else if(global_count <= 'd525) | |||
global_count <= global_count + 1'b1; | |||
else | |||
global_count <= 0; | |||
assign done = (reset_n == 0)||(global_count =='d524) ? 1'b1 : 1'b0; | |||
DOUT_M_AXIS # | |||
( | |||
// Width of S_AXIS address bus. The slave accepts the read and write addresses of width C_M_AXIS_TDATA_WIDTH. | |||
.C_M_AXIS_TDATA_WIDTH(`Dx_WIDTH), | |||
.C_S_AXIS_TDATA_WIDTH(`G), | |||
.DEPTH(27), | |||
.C_M_START_COUNT(2)) DOUT_STREAM | |||
( | |||
// Global ports | |||
.M_AXIS_ACLK(core_clk), | |||
.M_AXIS_ARESETN(reset_n), | |||
// Master Stream Ports. TVALID indicates that the master is driving a valid transfer, A transfer takes place when both TVALID and TREADY are asserted. | |||
.M_AXIS_TVALID(DOUT_TVALID), | |||
// TDATA is the primary payload that is used to provide the data that is passing across the interface from the master. | |||
.M_AXIS_TDATA(DOUT_TDATA), | |||
// TLAST indicates the boundary of a packet. | |||
.M_AXIS_TLAST(DOUT_TLAST), | |||
// TREADY indicates that the slave can accept a transfer in the current cycle. | |||
.M_AXIS_TREADY(s_axis_dout_tready), | |||
// Input from PBCH Encoder Core of Width 864 bits | |||
.S_AXIS_TDATA(msg_o), | |||
// Input from PBCH Encoder Core | |||
.DONE(done) | |||
); | |||
endmodule |
@@ -0,0 +1,45 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// | |||
// Design Name: Register | |||
// Module Name: register | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Tool Versions: VIVADO 2020.1 | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// register is written to synchronize a combiational logic w.r.t clock and reset signals | |||
module register #( | |||
parameter int WIDTH = 1, // width of the input and output of the register | |||
parameter logic [1:0] SR = 2'b00, // SET and RESET inputs of the register | |||
parameter logic [WIDTH-1:0] RST_VAL = {WIDTH{1'b0}} // reset value to be provided at the output when reset signal is active | |||
) ( | |||
input logic clk, // clock signal for register | |||
input logic rstb, // active low, synchronous reset | |||
input logic [WIDTH-1:0] din, // input to be registered | |||
output logic [WIDTH-1:0] dout // registered outputs | |||
); | |||
generate | |||
if(SR==2'b00) begin : NON_RESET_FLOP // if SR==00, irrespective of other signals the input needs to be registered | |||
always_ff @ (posedge clk) begin | |||
dout <= din; // registering input w.r.t posedge of clock signal | |||
end | |||
end : NON_RESET_FLOP | |||
else begin: RESET_FLOP // if SR!==00, input needs to be registered according to other signals w.r.t posedge of clock signal | |||
always_ff @ (posedge clk ) begin | |||
if (~rstb) // if reset is active | |||
if (SR == 2'b01) | |||
dout <= {WIDTH{1'b0}}; // if SR==01, reset the output | |||
else if (SR == 2'b10) | |||
dout <= {WIDTH{1'b1}}; // if SR==10, set the output | |||
else | |||
dout <= RST_VAL; // if SR==11, reset the output according the reset value provided | |||
else | |||
dout <= din; // if reset is inactive, register the input | |||
end | |||
end: RESET_FLOP | |||
endgenerate | |||
endmodule | |||
@@ -0,0 +1,61 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: ENCODER BIT SELECTION | |||
// Module Name: encoder_bit_selection_rtl | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: RTL code for bit selection, in order to change the length of a sequence from N to E, | |||
// also known as rate matching. | |||
// | |||
// | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module encoder_bit_selection_rtl | |||
#( | |||
parameter K = 164, | |||
parameter G = 1728, | |||
parameter C = 1, | |||
parameter E = G/C, | |||
parameter N=512 | |||
) | |||
( | |||
input wire clock_i, // system clock | |||
input wire reset_ni, // active low synchronous reset | |||
input wire [N-1:0] msg_i, // input message for bit selection | |||
output reg [E-1:0] msg_o // output message bit selection | |||
); | |||
localparam Y = E/N; | |||
localparam Z = E%N; | |||
integer i; | |||
generate | |||
always@(posedge clock_i) begin | |||
if(!reset_ni )begin | |||
msg_o <= 0; | |||
end | |||
else begin | |||
if(E>=N) | |||
begin | |||
for(i = 1;i <= Y;i = i+1) // Repitition // | |||
msg_o[((i*N)-1) -: N]<=msg_i[N-1:0]; // Assigning same N bits to output reg for E/N times | |||
if(Z != 0)begin | |||
msg_o[E-1:N*(Y)] <= msg_i[Z-1:0]; // Assingning remaining E%N bits | |||
end | |||
end | |||
else | |||
begin | |||
if((10000*(K/E)) <= (70000/16)) // Puncturing // | |||
msg_o[E-1:0] <= msg_i[N-1:N-E]; // Assigning last E bits to output register | |||
else // Shortening // | |||
msg_o[E-1:0] <= msg_i[E-1:0]; // Assigning first E bits to output register | |||
end | |||
end | |||
end | |||
endgenerate | |||
endmodule | |||
@@ -0,0 +1,55 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: ENCODER CORE | |||
// Module Name: encoder_core_rtl | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: RTL code for polar encoder core operation. | |||
// | |||
// encoder_core_rtl is written to encode an N-bit input message and produce an N-bit | |||
// encoded codeword as an output | |||
// | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module encoder_core_rtl | |||
#( | |||
parameter N = 512, // length of input and output messages for encoder_core_rtl | |||
localparam DEPTH = $clog2(N) // to derive depth of binary tree to carry out the operation of polar encoder core | |||
) | |||
( | |||
input wire clock_i, // system clock | |||
input wire reset_ni, // active low, synchronous reset | |||
input wire [N-1:0] msg_i, // input message to be encoded | |||
output reg [N-1:0] msg_o // output encoded codeword | |||
); | |||
reg [N-1:0] msg_1; // internal register to hold the encoded codeword throughout the operation | |||
integer i,j,k; // looping variables | |||
// instantiating a register(group of FF's) to hold the output and synchronize the module w.r.t clock and reset signals | |||
register #( | |||
.WIDTH(N), // overriding the width of register with the length of output to be registered | |||
.SR(2'b00), // overriding SR inputs of the register | |||
.RST_VAL({N{1'b0}}) // overriding the reset value with expected value in the output when reset is applied | |||
) REG ( | |||
.clk(clock_i), // connecting clock ports | |||
.rstb(reset_ni), // connecting reset ports | |||
.din(msg_1), // connecting input of register with the value that needs to be registered | |||
.dout(msg_o) // connecting the registered output with the output port of current module | |||
); | |||
// combinational always block for performing encoder operation | |||
always_comb begin | |||
msg_1 = msg_i; // temporary register is fed with input message | |||
for (i = 0; i <= DEPTH; i = i+1) begin : depth // to loop through the depth of binary tree | |||
for (j = 0; j <= (N-(2 ** i)); j = j+(2 ** i)) begin : limit // to find the boundaries of bits in different depths | |||
for (k = j; k < (j+(2 ** (i-1))); k = k+1) begin : count // to find the number of xor operations required to encode the message | |||
msg_1[k] = msg_1[k] ^ msg_1[k + (2 ** (i-1))]; // xor between two particular bits to be stored in another bit, based on the index calculated | |||
end : count | |||
end : limit | |||
end : depth | |||
end | |||
endmodule |
@@ -0,0 +1,86 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: ENCODER CRC ATTACHMENT | |||
// Module Name: encoder_crc_attachment_rtl | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: RTL code for calculation and attachment of CRC to a given message, according to selected polynomial. | |||
// | |||
//~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~// | |||
// If the CRC width i.e., P = X, // | |||
// it means that we are going to use a X degree polynomial of length X+1 bits, // | |||
// the crc_out is of X bits. // | |||
// CRC POLYNOMIALS used in Polar IP // | |||
// CRC6 =0x21 == 010_0001 // | |||
// CRC11 =0x621 == 0110_0010_0001 // | |||
// CRC16 =0x1021 == 0_0001_0000_0010_0001 // | |||
// CRC24C =0xB2B117 == 0_1011_0010_1011_0001_0001_0111 // | |||
//~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~^~~~~~// | |||
// | |||
// encoder_crc_attachment_rtl is written to calculate and attach CRC for a given message input. | |||
// | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module encoder_crc_attachment_rtl | |||
#( | |||
parameter PUCCH = 0, // Uplink Channel enable | |||
parameter PBCH = 0, // Broadcast Channel enable | |||
parameter N = 512, | |||
parameter A = 140, // Message width A if no segmentation needed, A'=A/2 if segmentation is needed. | |||
parameter P=24, | |||
parameter K = A+P // Message width after CRC is appended | |||
) | |||
( | |||
input wire clock_i, // System clock | |||
input wire reset_ni, // System reset,active low synchronous | |||
input wire [A-1:0] msg_i, // Input message bits | |||
output reg [K-1:0] msg_o // total message = message input + CRC bits | |||
); | |||
integer i; // looping variable | |||
wire [P:0] polynomial; // polynomial using which CRC needs to be calculated | |||
reg [K-1:0] polynomial_1='d0; // polynomial_1 is to store the right shifted polynomial in each step | |||
reg [K-1:0] msg_1='d0; // msg_1 is to hold the modified message in between the XOR operations | |||
reg [P-1:0] crc_out='d0; // Calculated CRC output for given msg_i | |||
reg [K-1:0] msg_2; // msg_2 is to hold the output msg after msg_i is appended with crc_out | |||
generate | |||
if (P == 'd6) //CRC-6 | |||
assign polynomial = 'h21; | |||
else if (P == 'd11) //CRC-11 | |||
assign polynomial = 'h621; | |||
else if (P == 'd24) //CRC-24C | |||
assign polynomial = 'h1d11a9b; | |||
else //CRC-16 | |||
assign polynomial = 'h1021; | |||
endgenerate | |||
// Procedural block to calculate CRC for input message bits. | |||
always@(*) begin | |||
polynomial_1 = { {(A-1){1'b0}}, polynomial[P:0] }; // initialization of polynomial_1 | |||
msg_1 = { {P{1'b0}}, msg_i[A-1:0] }; // initialization of msg_1 | |||
for (i = 0; i < A; i = i+1) begin // calculating CRC and storing in temporary internal register(A number of times) | |||
msg_1 = ( msg_1[i] )? ( msg_1 ^ polynomial_1 ) : ( msg_1 ^ {K{1'b0}} ); // exor with polynomial if message bit is 1, else exor with 0's. | |||
polynomial_1 = polynomial_1 << 1'b1; // left shifting the polynomial for each message bit | |||
end | |||
crc_out = msg_1[K-1 : A]; // assigning the internal register to CRC output | |||
msg_2 = { crc_out[P-1 : 0], msg_i[A-1 : 0] }; // the final message output | |||
end | |||
// instantiating a register(group of FF's) to hold the output and synchronize the module w.r.t clock and reset signals | |||
register #( | |||
.WIDTH(K), // overriding the width of register with the length of output to be registered | |||
.SR(2'b01), // overriding SR inputs of the register | |||
.RST_VAL({N{1'b0}}) // overriding the reset value with expected value in the output when reset is applied | |||
) REG ( | |||
.clk(clock_i), // connecting clock ports | |||
.rstb(reset_ni), // connecting reset ports | |||
.din(msg_2), // connecting input of register with the value that needs to be registered | |||
.dout(msg_o) // connecting the registered output with the output port of current module | |||
); | |||
endmodule | |||
@@ -0,0 +1,77 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: ENCODER CRC INTERLEAVING | |||
// Module Name: encoder_crc_interleaving_rtl | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: RTL code for interleaving the message attached with CRC, according to a CRC interleaver pattern. | |||
// | |||
// | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module encoder_crc_interleaving_rtl | |||
#( | |||
parameter K = 164, | |||
parameter ITLV = 0, | |||
parameter KMAX = 164 | |||
) | |||
( | |||
input wire clock_i, // system clock | |||
input wire reset_ni, // active low, synchronous reset | |||
input wire [K-1:0] msg_i, // input message to be interleaved | |||
output reg [K-1:0] msg_o // output crc interleaved message | |||
); | |||
integer k = 1'd0; | |||
integer j = 1'd0; | |||
integer i = 1'd0; | |||
integer m = 1'd0; | |||
reg [K-1:0] msg_1; // internal register to hold the interleaved message throughout the operation | |||
reg [7:0] pi [K-1:0]; //internal register for interleaving logic | |||
//interleaving pattern for interleaving the given message | |||
reg [7:0] pimax [163:0] = '{8'd163,8'd162,8'd161,8'd160,8'd159,8'd158,8'd157,8'd156,8'd155,8'd154,8'd153,8'd152,8'd151,8'd150,8'd149,8'd148,8'd147,8'd41,8'd146, | |||
8'd40,8'd145,8'd39,8'd144,8'd38,8'd18,8'd13,8'd143,8'd137,8'd86,8'd80,8'd75,8'd48,8'd37,8'd23,8'd17,8'd12,8'd142,8'd136,8'd131,8'd125, | |||
8'd117,8'd103,8'd100,8'd97,8'd85,8'd79,8'd74,8'd64,8'd47,8'd44,8'd36,8'd33,8'd30,8'd22,8'd16,8'd11,8'd6,8'd141,8'd135,8'd133,8'd130, | |||
8'd128,8'd124,8'd121,8'd116,8'd114,8'd112,8'd109,8'd107,8'd105,8'd102,8'd99,8'd96,8'd94,8'd92,8'd90,8'd84,8'd78,8'd73,8'd68,8'd63,8'd60, | |||
8'd57,8'd55,8'd52,8'd46,8'd43,8'd35,8'd32,8'd29,8'd27,8'd21,8'd15,8'd10,8'd8,8'd5,8'd3,8'd1,8'd140,8'd139,8'd138,8'd134,8'd132,8'd129, | |||
8'd127,8'd126,8'd123,8'd122,8'd120,8'd119,8'd118,8'd115,8'd113,8'd111,8'd110,8'd108,8'd106,8'd104,8'd101,8'd98,8'd95,8'd93,8'd91,8'd89, | |||
8'd88,8'd87,8'd83,8'd82,8'd81,8'd77,8'd76,8'd72,8'd71,8'd70,8'd69,8'd67,8'd66,8'd65,8'd62,8'd61,8'd59,8'd58,8'd56,8'd54,8'd53,8'd51, | |||
8'd50,8'd49,8'd45,8'd42,8'd34,8'd31,8'd28,8'd26,8'd25,8'd24,8'd20,8'd19,8'd14,8'd9,8'd7,8'd4,8'd2,8'd0}; | |||
// instantiating a register(group of FF's) to hold the output and synchronize the module w.r.t clock and reset signals | |||
register #( | |||
.WIDTH(K), // overriding the width of register with the length of output to be registered | |||
.SR(2'b00), // overriding SR inputs of the register | |||
.RST_VAL({K{1'b0}}) // overriding the reset value with expected value in the output when reset is applied | |||
) REG ( | |||
.clk(clock_i), // connecting clock ports | |||
.rstb(reset_ni), // connecting reset ports | |||
.din(msg_1), // connecting input of register with the value that needs to be registered | |||
.dout(msg_o) // connecting the registered output with the output port of current module | |||
); | |||
// combinational always block for performing crc interleaving operation | |||
always_comb begin | |||
if(ITLV == 0) begin | |||
for(i = 0 ; i < K ; i = i+1) | |||
pi[i] = i; | |||
end | |||
else begin | |||
k = 0; begin | |||
for( m = 0 ; (m < KMAX) ; m = m+1) | |||
if(pimax[m] >= (KMAX-K)) begin | |||
pi[k] = (pimax[m]-(KMAX-K)); | |||
k = k+1'b1; | |||
end | |||
end | |||
begin | |||
for( j = 'd0 ; j < K ; j = j+1) | |||
msg_1[j] = msg_i[pi[j]]; | |||
end | |||
end | |||
end | |||
endmodule |
@@ -0,0 +1,168 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: ENCODER FROZEN BIT INSERTION | |||
// Module Name: encoder_frozen_bit_insertion_rtl | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: RTL code for inserting frozen bits into information, according to given reliability sequence. | |||
// | |||
// encoder_frozen_bit_insertion_rtl is written to insert frozen bits in between information bits, according to reliability sequence | |||
// | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module encoder_frozen_bit_insertion_rtl1 | |||
#( | |||
parameter N = 512, // length of information+CRC+Frozen bits | |||
parameter K = 164 // length of information+CRC bits | |||
) | |||
( | |||
input wire clock_i, // system clock | |||
input wire reset_ni, // active low synchronous reset | |||
input wire [K-1:0] msg_i, // input information+CRC bits | |||
output reg [N-1:0] msg_o // information+CRC+frozen bits | |||
); | |||
reg [N-1:0] msg_1; // internal register to hold the output of frozen bit insertion | |||
reg [K-1:0] msg_2; | |||
int i,j,k='d0,p='d0,x='d0; // looping variables | |||
int q='d0; | |||
// storing the frozen locations in rel_seq array (reliability in ascending order) | |||
reg [9:0]rel_seq_512[511:0] = | |||
'{10'd511, 10'd510, 10'd509, 10'd507, 10'd503, 10'd495, 10'd508, 10'd479, 10'd506, 10'd505, 10'd447, 10'd501, 10'd494, | |||
10'd502, 10'd499, 10'd493, 10'd383, 10'd478, 10'd491, 10'd477, 10'd255, 10'd504, 10'd487, 10'd475, 10'd446, 10'd500, | |||
10'd471, 10'd445, 10'd498, 10'd382, 10'd443, 10'd492, 10'd497, 10'd381, 10'd463, 10'd490, 10'd439, 10'd476, 10'd486, | |||
10'd489, 10'd431, 10'd379, 10'd254, 10'd474, 10'd473, 10'd485, 10'd415, 10'd483, 10'd470, 10'd444, 10'd375, 10'd253, | |||
10'd367, 10'd247, 10'd469, 10'd441, 10'd442, 10'd462, 10'd251, 10'd438, 10'd467, 10'd351, 10'd496, 10'd461, 10'd380, | |||
10'd437, 10'd459, 10'd378, 10'd239, 10'd488, 10'd430, 10'd484, 10'd319, 10'd435, 10'd377, 10'd455, 10'd472, 10'd223, | |||
10'd414, 10'd427, 10'd482, 10'd373, 10'd252, 10'd429, 10'd468, 10'd366, 10'd413, 10'd481, 10'd371, 10'd250, 10'd466, | |||
10'd423, 10'd374, 10'd440, 10'd365, 10'd411, 10'd249, 10'd460, 10'd350, 10'd246, 10'd465, 10'd436, 10'd407, 10'd191, | |||
10'd127, 10'd363, 10'd458, 10'd245, 10'd349, 10'd434, 10'd399, 10'd457, 10'd359, 10'd238, 10'd428, 10'd376, 10'd318, | |||
10'd454, 10'd243, 10'd347, 10'd433, 10'd237, 10'd453, 10'd426, 10'd222, 10'd317, 10'd372, 10'd343, 10'd412, 10'd235, | |||
10'd451, 10'd425, 10'd422, 10'd370, 10'd221, 10'd315, 10'd480, 10'd335, 10'd364, 10'd190, 10'd369, 10'd248, 10'd231, | |||
10'd410, 10'd421, 10'd311, 10'd219, 10'd409, 10'd362, 10'd464, 10'd406, 10'd419, 10'd348, 10'd215, 10'd361, 10'd189, | |||
10'd244, 10'd303, 10'd405, 10'd358, 10'd456, 10'd346, 10'd398, 10'd242, 10'd126, 10'd236, 10'd187, 10'd357, 10'd432, | |||
10'd207, 10'd403, 10'd397, 10'd452, 10'd345, 10'd241, 10'd316, 10'd342, 10'd125, 10'd234, 10'd183, 10'd287, 10'd355, | |||
10'd395, 10'd424, 10'd314, 10'd220, 10'd341, 10'd123, 10'd175, 10'd233, 10'd334, 10'd450, 10'd313, 10'd391, 10'd230, | |||
10'd368, 10'd218, 10'd339, 10'd119, 10'd333, 10'd310, 10'd420, 10'd159, 10'd229, 10'd408, 10'd217, 10'd449, 10'd188, | |||
10'd309, 10'd214, 10'd331, 10'd111, 10'd360, 10'd302, 10'd418, 10'd227, 10'd404, 10'd186, 10'd213, 10'd417, 10'd301, | |||
10'd307, 10'd356, 10'd402, 10'd327, 10'd95, 10'd206, 10'd240, 10'd344, 10'd396, 10'd185, 10'd401, 10'd211, 10'd354, | |||
10'd299, 10'd286, 10'd182, 10'd205, 10'd124, 10'd232, 10'd285, 10'd295, 10'd181, 10'd394, 10'd340, 10'd63, 10'd203, | |||
10'd353, 10'd448, 10'd122, 10'd283, 10'd393, 10'd174, 10'd390, 10'd312, 10'd338, 10'd228, 10'd179, 10'd199, 10'd121, | |||
10'd173, 10'd389, 10'd332, 10'd118, 10'd337, 10'd158, 10'd279, 10'd271, 10'd416, 10'd216, 10'd308, 10'd387, 10'd226, | |||
10'd330, 10'd171, 10'd212, 10'd117, 10'd110, 10'd329, 10'd157, 10'd306, 10'd326, 10'd225, 10'd167, 10'd115, 10'd184, | |||
10'd109, 10'd300, 10'd305, 10'd210, 10'd155, 10'd325, 10'd352, 10'd400, 10'd298, 10'd204, 10'd94, 10'd284, 10'd209, | |||
10'd151, 10'd180, 10'd107, 10'd297, 10'd392, 10'd323, 10'd202, 10'd93, 10'd294, 10'd178, 10'd103, 10'd143, 10'd282, | |||
10'd62, 10'd336, 10'd201, 10'd120, 10'd172, 10'd198, 10'd91, 10'd388, 10'd293, 10'd177, 10'd278, 10'd281, 10'd61, | |||
10'd170, 10'd116, 10'd197, 10'd87, 10'd156, 10'd277, 10'd114, 10'd169, 10'd59, 10'd291, 10'd275, 10'd270, 10'd195, | |||
10'd166, 10'd224, 10'd108, 10'd269, 10'd79, 10'd154, 10'd113, 10'd328, 10'd55, 10'd106, 10'd165, 10'd153, 10'd150, | |||
10'd386, 10'd208, 10'd324, 10'd385, 10'd267, 10'd47, 10'd92, 10'd163, 10'd296, 10'd304, 10'd105, 10'd102, 10'd149, | |||
10'd263, 10'd322, 10'd292, 10'd90, 10'd200, 10'd31, 10'd321, 10'd142, 10'd176, 10'd147, 10'd101, 10'd141, 10'd196, | |||
10'd290, 10'd89, 10'd280, 10'd60, 10'd86, 10'd99, 10'd139, 10'd168, 10'd58, 10'd276, 10'd85, 10'd194, 10'd289, | |||
10'd78, 10'd135, 10'd112, 10'd57, 10'd83, 10'd54, 10'd274, 10'd268, 10'd164, 10'd77, 10'd152, 10'd193, 10'd53, | |||
10'd162, 10'd104, 10'd273, 10'd266, 10'd75, 10'd46, 10'd148, 10'd51, 10'd100, 10'd45, 10'd161, 10'd265, 10'd262, | |||
10'd71, 10'd146, 10'd30, 10'd140, 10'd88, 10'd98, 10'd43, 10'd29, 10'd261, 10'd145, 10'd138, 10'd84, 10'd259, 10'd39, | |||
10'd97, 10'd27, 10'd56, 10'd82, 10'd137, 10'd76, 10'd384, 10'd134, 10'd23, 10'd52, 10'd133, 10'd320, 10'd15, 10'd73, | |||
10'd50, 10'd81, 10'd131, 10'd44, 10'd70, 10'd192, 10'd288, 10'd160, 10'd272, 10'd74, 10'd49, 10'd42, 10'd69, 10'd28, | |||
10'd144, 10'd41, 10'd67, 10'd96, 10'd38, 10'd264, 10'd260, 10'd136, 10'd22, 10'd25, 10'd37, 10'd80, 10'd26, 10'd258, | |||
10'd35, 10'd132, 10'd21, 10'd257, 10'd72, 10'd14, 10'd48, 10'd13, 10'd19, 10'd130, 10'd68, 10'd40, 10'd11, 10'd66, | |||
10'd129, 10'd7, 10'd36, 10'd24, 10'd34, 10'd256, 10'd20, 10'd65, 10'd33, 10'd12, 10'd128, 10'd18, 10'd10, 10'd17, | |||
10'd6, 10'd9, 10'd64, 10'd5, 10'd3, 10'd32, 10'd16, 10'd8, 10'd4, 10'd2, 10'd1, 10'd0} ; | |||
reg [9:0]rel_seq_256[255:0] = | |||
'{10'd255, 10'd254, 10'd253, 10'd247, 10'd251, 10'd239, 10'd223, 10'd252, 10'd250, 10'd249, 10'd246, 10'd191, 10'd127, | |||
10'd245, 10'd238, 10'd243, 10'd237, 10'd222, 10'd235, 10'd221, 10'd190, 10'd248, 10'd231, 10'd219, 10'd215, 10'd189, | |||
10'd244, 10'd242, 10'd126, 10'd236, 10'd187, 10'd207, 10'd241, 10'd125, 10'd234, 10'd183, 10'd220, 10'd123, 10'd175, | |||
10'd233, 10'd230, 10'd218, 10'd119, 10'd159, 10'd229, 10'd217, 10'd188, 10'd214, 10'd111, 10'd227, 10'd186, 10'd213, | |||
10'd95, 10'd206, 10'd240, 10'd185, 10'd211, 10'd182, 10'd205, 10'd124, 10'd232, 10'd181, 10'd63, 10'd203, 10'd122, | |||
10'd174, 10'd228, 10'd179, 10'd199, 10'd121, 10'd173, 10'd118, 10'd158, 10'd216, 10'd226, 10'd171, 10'd212, 10'd117, | |||
10'd110, 10'd157, 10'd225, 10'd167, 10'd115, 10'd184, 10'd109, 10'd210, 10'd155, 10'd204, 10'd94, 10'd209, 10'd151, | |||
10'd180, 10'd107, 10'd202, 10'd93, 10'd178, 10'd103, 10'd143, 10'd62, 10'd201, 10'd120, 10'd172, 10'd198, 10'd91, | |||
10'd177, 10'd61, 10'd170, 10'd116, 10'd197, 10'd87, 10'd156, 10'd114, 10'd169, 10'd59, 10'd195, 10'd166, 10'd224, | |||
10'd108, 10'd79, 10'd154, 10'd113, 10'd55, 10'd106, 10'd165, 10'd153, 10'd150, 10'd208, 10'd47, 10'd92, 10'd163, | |||
10'd105, 10'd102, 10'd149, 10'd90, 10'd200, 10'd31, 10'd142, 10'd176, 10'd147, 10'd101, 10'd141, 10'd196, 10'd89, | |||
10'd60, 10'd86, 10'd99, 10'd139, 10'd168, 10'd58, 10'd85, 10'd194, 10'd78, 10'd135, 10'd112, 10'd57, 10'd83, 10'd54, | |||
10'd164, 10'd77, 10'd152, 10'd193, 10'd53, 10'd162, 10'd104, 10'd75, 10'd46, 10'd148, 10'd51, 10'd100, 10'd45, 10'd161, | |||
10'd71, 10'd146, 10'd30, 10'd140, 10'd88, 10'd98, 10'd43, 10'd29, 10'd145, 10'd138, 10'd84, 10'd39, 10'd97, 10'd27, | |||
10'd56, 10'd82, 10'd137, 10'd76, 10'd134, 10'd23, 10'd52, 10'd133, 10'd15, 10'd73, 10'd50, 10'd81, 10'd131, 10'd44, | |||
10'd70, 10'd192, 10'd160, 10'd74, 10'd49, 10'd42, 10'd69, 10'd28, 10'd144, 10'd41, 10'd67, 10'd96, 10'd38, 10'd136, | |||
10'd22, 10'd25, 10'd37, 10'd80, 10'd26, 10'd35, 10'd132, 10'd21, 10'd72, 10'd14, 10'd48, 10'd13, 10'd19, 10'd130, | |||
10'd68, 10'd40, 10'd11, 10'd66, 10'd129, 10'd7, 10'd36, 10'd24, 10'd34, 10'd20, 10'd65, 10'd33, 10'd12, 10'd128, | |||
10'd18, 10'd10, 10'd17, 10'd6, 10'd9, 10'd64, 10'd5, 10'd3, 10'd32, 10'd16, 10'd8, 10'd4, 10'd2, 10'd1, 10'd0}; | |||
reg [9:0]rel_seq_128[127:0] = | |||
'{10'd127, 10'd126, 10'd125, 10'd123, 10'd119, 10'd111, 10'd95, 10'd124, 10'd63, 10'd122, 10'd121, 10'd118, 10'd117, 10'd110, | |||
10'd115, 10'd109, 10'd94, 10'd107, 10'd93, 10'd103, 10'd62, 10'd120, 10'd91, 10'd61, 10'd116, 10'd87, 10'd114, 10'd59, 10'd108, | |||
10'd79, 10'd113, 10'd55, 10'd106, 10'd47, 10'd92, 10'd105, 10'd102, 10'd90, 10'd31, 10'd101, 10'd89, 10'd60, 10'd86, 10'd99, | |||
10'd58, 10'd85, 10'd78, 10'd112, 10'd57, 10'd83, 10'd54, 10'd77, 10'd53, 10'd104, 10'd75, 10'd46, 10'd51, 10'd100, 10'd45, | |||
10'd71, 10'd30, 10'd88, 10'd98, 10'd43, 10'd29, 10'd84, 10'd39, 10'd97, 10'd27, 10'd56, 10'd82, 10'd76, 10'd23, 10'd52, 10'd15, | |||
10'd73, 10'd50, 10'd81, 10'd44, 10'd70, 10'd74, 10'd49, 10'd42, 10'd69, 10'd28, 10'd41, 10'd67, 10'd96, 10'd38, 10'd22, 10'd25, | |||
10'd37, 10'd80, 10'd26, 10'd35, 10'd21, 10'd72, 10'd14, 10'd48, 10'd13, 10'd19, 10'd68, 10'd40, 10'd11, 10'd66, 10'd7, 10'd36, | |||
10'd24, 10'd34, 10'd20, 10'd65, 10'd33, 10'd12, 10'd18, 10'd10, 10'd17, 10'd6, 10'd9, 10'd64, 10'd5, 10'd3, 10'd32, 10'd16, | |||
10'd8, 10'd4, 10'd2, 10'd1, 10'd0}; | |||
reg [9:0]rel_seq_64[63:0] = | |||
'{10'd63, 10'd62, 10'd61, 10'd59, 10'd55, 10'd47, 10'd31, 10'd60, 10'd58, 10'd57, 10'd54, 10'd53, 10'd46, 10'd51, 10'd45, 10'd30, | |||
10'd43, 10'd29, 10'd39, 10'd27, 10'd56, 10'd23, 10'd52, 10'd15, 10'd50, 10'd44, 10'd49, 10'd42, 10'd28, 10'd41, 10'd38, 10'd22, | |||
10'd25, 10'd37, 10'd26, 10'd35, 10'd21, 10'd14, 10'd48, 10'd13, 10'd19, 10'd40, 10'd11, 10'd7, 10'd36, 10'd24, 10'd34, 10'd20, 10'd33, | |||
10'd12, 10'd18, 10'd10, 10'd17, 10'd6, 10'd9, 10'd5, 10'd3, 10'd32, 10'd16, 10'd8, 10'd4, 10'd2, 10'd1, 10'd0}; | |||
reg [9:0]rel_seq_32[31:0] = | |||
'{10'd31, 10'd30, 10'd29, 10'd27, 10'd23, 10'd15, 10'd28, 10'd22, 10'd25, 10'd26, 10'd21, 10'd14, 10'd13, 10'd19, 10'd11, 10'd7, 10'd24, | |||
10'd20, 10'd12, 10'd18, 10'd10, 10'd17, 10'd6, 10'd9, 10'd5, 10'd3, 10'd16, 10'd8, 10'd4, 10'd2, 10'd1, 10'd0}; | |||
always@(posedge clock_i) | |||
begin : insert_frz_zeroes | |||
if(q == 0) | |||
msg_2 <= msg_i; | |||
if(q >= (N-K) ) begin : insert_msg_crc | |||
case(N) | |||
32 : msg_1[rel_seq_32[q]] <= msg_2[x]; // filling remaining most reliable K positions with information+CRC bits | |||
64 : msg_1[rel_seq_64[q]] <= msg_2[x]; | |||
128 : msg_1[rel_seq_128[q]] <= msg_2[x]; | |||
256 : msg_1[rel_seq_256[q]] <= msg_2[x]; | |||
512 : msg_1[rel_seq_512[q]] <= msg_2[x]; | |||
default:msg_1 <= 'b0; | |||
endcase | |||
if(x < K) | |||
x ++; | |||
else | |||
x <= 0; | |||
end : insert_msg_crc // N - K bits need to be frozen | |||
else begin | |||
case(N) | |||
32 : msg_1[rel_seq_32[q]] <= 1'b0; // filling the least reliable frozen positions with 0's | |||
64 : msg_1[rel_seq_64[q]] <= 1'b0; | |||
128 : msg_1[rel_seq_128[q]] <= 1'b0; | |||
256 : msg_1[rel_seq_256[q]] <= 1'b0; | |||
512 : msg_1[rel_seq_512[q]] <= 1'b0; | |||
default:msg_1 <= 'b0; | |||
endcase | |||
end | |||
if(msg_2 == msg_i && q<N ) | |||
q <= q+1; | |||
else | |||
q <= 0; | |||
end : insert_frz_zeroes | |||
always@(posedge clock_i) | |||
if(!reset_ni) | |||
msg_o <= 0; | |||
else if(q==N) | |||
msg_o <= msg_1; | |||
else | |||
msg_o <= msg_o; | |||
endmodule |
@@ -0,0 +1,78 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// Design Name: ENCODER SUB-BLOCK INTERLEAVING | |||
// Module Name: encoder_sub_block_interleaving_rtl | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: RTL code for sub block interleaving, in order to interleave the sub blocks of encoded codeword. | |||
// | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module encoder_sub_block_interleaving_rtl#( | |||
parameter N=512 // input and output sequence length | |||
// parameter to break down the input message into 32- sub blocks of euqal length, S=N/32 | |||
) ( | |||
input wire clock_i, | |||
input wire reset_ni, | |||
input wire [N-1:0] msg_i, // input message for sub block interleaver | |||
output reg [N-1:0] msg_o // output message after sub block interleaving | |||
); | |||
localparam S=(N >> 3'd5); // parameter to break down the input message into 32- sub blocks of euqal length, S=N/32 | |||
reg [4:0] sbi_pat [31:0] = '{5'd31, 5'd30, 5'd29, 5'd27, | |||
5'd28, 5'd26,5'd25, 5'd24, | |||
5'd23,5'd15,5'd22, 5'd14, | |||
5'd21, 5'd13, 5'd20, 5'd12, | |||
5'd19, 5'd11, 5'd18, 5'd10, | |||
5'd17, 5'd9, 5'd16, 5'd8, | |||
5'd7, 5'd6, 5'd5, 5'd3, | |||
5'd4, 5'd2, 5'd1, 5'd0}; | |||
logic [N-1:0] msg_1; | |||
logic sub_blocks [31:0] [S-1:0]; //register to store the sub divided blocks | |||
logic temp [31:0] [S-1:0]; //register to store the interleaved sub blocks | |||
integer i,j,k,p,q,r; //looping variables | |||
// instantiating a register(group of FF's) to hold the output and synchronize the module w.r.t clock and reset signals | |||
register #( | |||
.WIDTH(N), // overriding the width of register with the length of output to be registered | |||
.SR(2'b00), // overriding SR inputs of the register | |||
.RST_VAL({N{1'b0}}) // overriding the reset value with expected value in the output when reset is applied | |||
) REG ( | |||
.clk(clock_i), // connecting clock ports | |||
.rstb(reset_ni), // connecting reset ports | |||
.din(msg_1), // connecting input of register with the value that needs to be registered | |||
.dout(msg_o) // connecting the registered output with the output port of current module | |||
); | |||
always_comb begin | |||
//breaking down the message into 32 bit sub blocks of width N/32 | |||
begin | |||
for(j = 0 ; j < 32 ; j=j+1) begin | |||
for (i = 0 ; i < S ; i = i+1) begin | |||
sub_blocks[j][i] = msg_i[(j*S)+i]; | |||
end | |||
end | |||
end | |||
//interleaving the subblocks according to the interleaving pattern | |||
begin | |||
for(p = 0 ; p < 32 ; p = p+1) begin | |||
temp[p] = sub_blocks[sbi_pat[p]]; | |||
end | |||
end | |||
//assigning interleaved bits to the output | |||
begin | |||
for(q = 0 ; q < 32 ; q = q+1) begin | |||
for (r = 0 ; r < S ; r = r+1) begin | |||
msg_1[(q*S)+r] = temp[q][r]; | |||
end | |||
end | |||
end | |||
end | |||
endmodule |
@@ -0,0 +1,127 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PRIVATE LIMITED | |||
// | |||
// Design Name: POLAE_ENCODER | |||
// Module Name: POLAR_ENCODER | |||
// Project Name: POLAR ENCODER-DECODER | |||
// Target Devices: Zynq UltraScale+ ZCU111 Evaluation Platform (xczu28dr-ffvg1517-2-e) | |||
// Tool Versions: VIVADO 2020.1 | |||
// Description: RTL code for integration of all sub blocks of polar encoder | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module POLAR_ENCODER | |||
#( | |||
parameter PUCCH=0, // Uplink Channel enable | |||
parameter PBCH=1, // Broadcast Channel enable | |||
parameter A=32, // Message width A if no segmentation needed, A'=A/2 if segmentation is needed. | |||
parameter P=24, | |||
parameter G=864, // Length of output | |||
parameter C=1, // Value of C=2 if segmentation need to be done otherwise C=1 | |||
parameter E=G/C, // Value of E based on G and C | |||
parameter K=A+P, // Length of information+CRC width | |||
parameter n_min=5, | |||
parameter n_max=9, | |||
parameter n_1= ((E<=((9/8)*(2**(($clog2(E))-1))))&&((K/E)<(9/16)))? ($clog2(E)-1) : $clog2(E), | |||
parameter n_2= $clog2(8*K), | |||
parameter min_n1_n2= (n_1 >= n_2)? n_2 : n_1, | |||
parameter min_n1_n2_nmax = (min_n1_n2 >= n_max) ? n_max : min_n1_n2 , | |||
parameter n=(min_n1_n2_nmax >= n_min)? min_n1_n2_nmax : n_min, | |||
parameter N=2**n, | |||
parameter ITLV=1, // Interleave flag for CRC interleaving process | |||
parameter KMAX=164 // Maximum value of K for CRC interleaving | |||
) | |||
( | |||
input clock_i, // input clock signal | |||
input reset_ni, // input reset | |||
input wire [A-1:0] msg_i, // input message bits | |||
output reg [G-1:0] msg_o // output bits | |||
); | |||
wire [K-1:0] msg_1; // output of CRC attachment | |||
wire [K-1:0] msg_2; // output of CRC scrambling | |||
wire [K-1:0] msg_x; // output of CRC interleaving | |||
wire [N-1:0] msg_3; // output of frozen insertion | |||
wire [N-1:0] msg_4; // output of encoder core | |||
wire [N-1:0] msg_5; // output of sub block interleaving | |||
wire [G-1:0] msg_6; // output of bit selection | |||
if(PBCH) begin | |||
encoder_crc_attachment_rtl #( | |||
.PUCCH( PUCCH ), // Uplink Channel enable | |||
.PBCH( PBCH ), // Broadcast Channel enable | |||
.A(A), // Message width A if no segmentation needed, A'=A/2 if segmentation is needed. | |||
.N(N) | |||
) ENCODER_PBCH_CRC_ATTACHMENT ( | |||
.clock_i(clock_i), // System clock | |||
.reset_ni(reset_ni), // System reset,active low synchronous | |||
.msg_i( msg_i), // Input message bits | |||
.msg_o( msg_1) // total message = message input + CRC bits | |||
); | |||
encoder_crc_interleaving_rtl#( | |||
.K(K), | |||
.ITLV(ITLV), | |||
.KMAX(KMAX) | |||
) ENCODER_PBCH_CRC_INTERLEAVING ( | |||
.clock_i(clock_i), // system clock | |||
.reset_ni(reset_ni), // active low, synchronous reset | |||
.msg_i( msg_1), // input message to be interleaved | |||
.msg_o( msg_2) // output crc interleaved message | |||
); | |||
encoder_frozen_bit_insertion_rtl1 #( | |||
.N(N), // length of information+CRC+Frozen bits | |||
.K(K) // length of information+CRC bits | |||
) ENCODER_PBCH_FROZEN_INSERTION ( | |||
.clock_i(clock_i), // system clock | |||
.reset_ni(reset_ni), // active low synchronous reset | |||
.msg_i( msg_2), // input information+CRC bits | |||
.msg_o(msg_3) // information+CRC+frozen bits | |||
); | |||
encoder_core_rtl #( | |||
.N(N) // length of input and output messages for encoder_core_rtl | |||
) ENCODER_PBCH_CORE ( | |||
.clock_i(clock_i), // system clock | |||
.reset_ni(reset_ni), // active low, synchronous reset | |||
.msg_i( msg_3), // input message to be encoded | |||
.msg_o(msg_4) // output encoded codeword | |||
); | |||
encoder_sub_block_interleaving_rtl #( | |||
.N( N) // input and output sequence length | |||
) ENCODER_PBCH_SUB_BLOCK_INTERLEAVING ( | |||
.clock_i(clock_i), | |||
.reset_ni(reset_ni), | |||
.msg_i(msg_4), // input message for sub block interleaver | |||
.msg_o(msg_5) // output message after sub block interleaving | |||
); | |||
encoder_bit_selection_rtl #( | |||
.K(K), | |||
.G(G), | |||
.C(C), | |||
.E(E), | |||
.N(N) | |||
) ENCODER_PBCH_BIT_SELECTION ( | |||
.clock_i(clock_i), // system clock | |||
.reset_ni(reset_ni), // active low, synchronous reset | |||
.msg_i(msg_5), // input message for bit selection | |||
.msg_o(msg_6) // output message after bit selection | |||
); | |||
end | |||
always@(posedge clock_i) // registering output with respect to clock | |||
if(!reset_ni) | |||
msg_o <=0; | |||
else | |||
begin | |||
msg_o <=msg_6; | |||
end | |||
endmodule | |||
@@ -0,0 +1,226 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PVT LTD | |||
// Design Name: | |||
// Module Name: FIFO | |||
// Project Name: | |||
////////////////////////////////////////////////////////////////////////////////// | |||
/* | |||
Description | |||
=========== | |||
I/Os | |||
---- | |||
rst low active, either sync. or async. master reset (see below how to select) | |||
clr synchronous clear (just like reset but always synchronous), high active | |||
re read enable, synchronous, high active | |||
we read enable, synchronous, high active | |||
din Data Input | |||
dout Data Output | |||
full Indicates the FIFO is full (combinatorial output) | |||
full_r same as above, but registered output (see note below) | |||
empty Indicates the FIFO is empty | |||
empty_r same as above, but registered output (see note below) | |||
full_n Indicates if the FIFO has space for N entries (combinatorial output) | |||
full_n_r same as above, but registered output (see note below) | |||
empty_n Indicates the FIFO has at least N entries (combinatorial output) | |||
empty_n_r same as above, but registered output (see note below) | |||
level indicates the FIFO level: | |||
2'b00 0-25% full | |||
2'b01 25-50% full | |||
2'b10 50-75% full | |||
2'b11 %75-100% full | |||
combinatorial vs. registered status outputs | |||
------------------------------------------- | |||
Both the combinatorial and registered status outputs have exactly the same | |||
synchronous timing. Meaning they are being asserted immediately at the clock | |||
edge after the last read or write. The combinatorial outputs however, pass | |||
through several levels of logic before they are output. The registered status | |||
outputs are direct outputs of a flip-flop. The reason both are provided, is | |||
that the registered outputs require quite a bit of additional logic inside | |||
the FIFO. If you can meet timing of your device with the combinatorial | |||
outputs, use them ! The FIFO will be smaller. If the status signals are | |||
in the critical pass, use the registered outputs, they have a much smaller | |||
output delay (actually only Tcq). | |||
Parameters | |||
---------- | |||
The FIFO takes 3 parameters: | |||
dw Data bus width | |||
aw Address bus width (Determines the FIFO size by evaluating 2^aw) | |||
n N is a second status threshold constant for full_n and empty_n | |||
*/ | |||
// Selecting Sync. or Async Reset | |||
// ------------------------------ | |||
// Uncomment one of the two lines below. The first line for | |||
// synchronous reset, the second for asynchronous reset | |||
`define SC_FIFO_ASYNC_RESET //Uncomment for Syncr. reset | |||
//`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset | |||
module fifo#(parameter dw=32,aw=5,n=32)(clk, rst, din, we, dout, re, | |||
full, empty, full_r, empty_r, | |||
full_n, empty_n, full_n_r, empty_n_r, | |||
level,count); | |||
parameter max_size = 1<<aw; | |||
input clk, rst; | |||
input [dw-1:0] din; | |||
input we; | |||
output [dw-1:0] dout; | |||
input re; | |||
output full, full_r; | |||
output empty, empty_r; | |||
output full_n, full_n_r; | |||
output empty_n, empty_n_r; | |||
output [1:0] level; | |||
output [aw:0] count; | |||
//////////////////////////////////////////////////////////////////// | |||
// | |||
// Local Wires | |||
// | |||
wire wen; // Write Enable | |||
wire ren; // Read Enable | |||
reg [aw-1:0] wp; | |||
wire [aw-1:0] wp_pl1; | |||
wire [aw-1:0] wp_pl2; | |||
reg [aw-1:0] rp; | |||
wire [aw-1:0] rp_pl1; | |||
reg full_r; | |||
reg empty_r; | |||
reg gb; | |||
reg gb2; | |||
reg [aw:0] cnt; | |||
wire full_n, empty_n; | |||
reg full_n_r, empty_n_r; | |||
// Write Only when FIFO isn't full & write enable is there | |||
assign wen = (!full && we) ? 1'b1 : 1'b0; | |||
assign ren = (!empty && re) ? 1'b1 : 1'b0; | |||
assign count = cnt; | |||
//////////////////////////////////////////////////////////////////// | |||
// Memory Block | |||
//////////////////////////////////////////////////////////////////// | |||
simple_dual_port_ram #(.WIDTH(dw),.DEPTH(n),.AW(aw))u0(.clk(clk),.wea(wen),.enb(ren),.addra(wp),.addrb(rp),.dia(din),.dob(dout)); | |||
//////////////////////////////////////////////////////////////////// | |||
// Misc Logic | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) wp <= #1 {aw{1'b0}}; | |||
else | |||
if(we) wp <= #1 wp_pl1; | |||
assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1}; | |||
assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10}; | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) rp <= #1 {aw{1'b0}}; | |||
else | |||
if(re) rp <= #1 rp_pl1; | |||
assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1}; | |||
//////////////////////////////////////////////////////////////////// | |||
// Combinatorial Full & Empty Flags | |||
// | |||
assign empty = ((wp == rp) & !gb); | |||
assign full = ((wp == rp) & gb); | |||
// Guard Bit ... | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) gb <= #1 1'b0; | |||
else | |||
if((wp_pl1 == rp) & we) gb <= #1 1'b1; | |||
else | |||
if(re) gb <= #1 1'b0; | |||
//////////////////////////////////////////////////////////////////// | |||
// Registered Full & Empty Flags | |||
// | |||
// Guard Bit ... | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) gb2 <= #1 1'b0; | |||
else | |||
if((wp_pl2 == rp) & we) gb2 <= #1 1'b1; | |||
else | |||
if((wp != rp) & re) gb2 <= #1 1'b0; | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) full_r <= #1 1'b0; | |||
else | |||
if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1; | |||
else | |||
if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0; | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) empty_r <= #1 1'b1; | |||
else | |||
if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0; | |||
else | |||
if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1; | |||
//////////////////////////////////////////////////////////////////// | |||
// Combinatorial Full_n & Empty_n Flags | |||
assign empty_n = cnt < n; | |||
assign full_n = !(cnt < (max_size-n+1)); | |||
assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2]; | |||
// N entries status | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) cnt <= #1 {aw+1{1'b0}}; | |||
else | |||
if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1}; | |||
else | |||
if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1}; | |||
//////////////////////////////////////////////////////////////////// | |||
// Registered Full_n & Empty_n Flags | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) empty_n_r <= #1 1'b1; | |||
else | |||
if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0; | |||
else | |||
if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1; | |||
always @(posedge clk `SC_FIFO_ASYNC_RESET) | |||
if(!rst) full_n_r <= #1 1'b0; | |||
else | |||
if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1; | |||
else | |||
if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0; | |||
//////////////////////////////////////////////////////////////////// | |||
// Sanity Check | |||
always @(posedge clk) | |||
if(we & full) | |||
$display("%m WARNING: Writing while fifo is FULL (%t)",$time); | |||
always @(posedge clk) | |||
if(re & empty) | |||
$display("%m WARNING: Reading while fifo is EMPTY (%t)",$time); | |||
endmodule | |||
@@ -0,0 +1,28 @@ | |||
`timescale 1ns / 1ps | |||
////////////////////////////////////////////////////////////////////////////////// | |||
// Company: BITSILICA PVT LTD | |||
// Design Name: | |||
// Module Name: simple_dual_port_ram | |||
// Project Name: | |||
////////////////////////////////////////////////////////////////////////////////// | |||
module simple_dual_port_ram#(parameter WIDTH = 32, DEPTH = 16,AW = 4)(clk,enb,wea,addra,addrb,dia,dob); | |||
input clk,wea,enb; | |||
input [AW -1:0] addra,addrb; | |||
input [WIDTH -1:0] dia; | |||
output [WIDTH -1:0] dob; | |||
reg [WIDTH -1:0] dob; | |||
reg [WIDTH -1:0] ram [DEPTH -1:0]; | |||
always @(posedge clk) begin | |||
if (wea) | |||
ram[addra] <= dia; | |||
end | |||
always @(posedge clk) begin | |||
if (enb) | |||
dob <= ram[addrb]; | |||
end | |||
endmodule |