Altera_Forum
Honored Contributor
16 years agoramstyle attribute in Quartus synthesis
I am trying to create some verilog that will receive a message with a set of sample data from a Nios processor and send the samples out on digital i/o pins sequentially. The message size is 512 bytes and this takes up too many LEs in my design if I implement the message buffer as a register. I have been looking into ways to use M9K blocks instead as the design has plenty of those available. I've tried to use:
(* ramstyle="M9K" *) reg act_message;
instead of
reg act_message;
but that doesn't affect the LE usage. Am I using the command incorrectly? Is there a Quartus setting that needs to be changed to use this? Is there a better way to solve the problem? The full verilog file is below:
module dio_bus_interface
(
//AVALON memory mapped interface SIGNALS
clk,
reset_n,
chipselect_n,
address,
read,
readdata,
write,
writedata,
//internal signals to the dio control module
w_dio_output_bank1,
w_dio_input_bank1,
w_dio_dir_bank1,
);
input clk;
input reset_n;
input chipselect_n;
input address;
input read;
output readdata;
reg readdata;
input write;
input writedata;
output w_dio_output_bank1;
reg w_dio_output_bank1;
input w_dio_input_bank1;
output w_dio_dir_bank1;
reg w_dio_dir_bank1;
//Register addresses
parameter WRITE_DIO_REG_ADDRESS_BANK1 = 4'b 0000;
parameter READ_DIO_REG_ADDRESS_BANK1 = 4'b 0001;
parameter SET_DIO_INPUT_REG_ADDRESS_BANK1 = 4'b 0010;
parameter SET_DIO_OUTPUT_REG_ADDRESS_BANK1 = 4'b 0011;
parameter SETUP_DIO_SEQUENCE_REG_ADDRESS_BANK1 = 4'b 1000;
//Set DIO CH1 as input or output
wire set_dio_input_register_ch1;
wire set_dio_output_register_ch1;
assign set_dio_input_register_ch1 = ((chipselect_n == 1'b0) & (write == 1'b1) & (address == SET_DIO_INPUT_REG_ADDRESS_BANK1));
assign set_dio_output_register_ch1 = ((chipselect_n == 1'b0) & (write == 1'b1) & (address == SET_DIO_OUTPUT_REG_ADDRESS_BANK1));
always @ (posedge clk or negedge reset_n)
begin
if(~reset_n)
w_dio_dir_bank1 <= 1'b1;
else if (set_dio_output_register_ch1) //set ch1 as output
w_dio_dir_bank1 <= 1'b0;
else if(set_dio_input_register_ch1) //set ch1 as input
w_dio_dir_bank1 <= 1'b1;
end
// ************************************************
// Setup digital output sequence
// ************************************************
(* ramstyle="M9K" *) reg act_message;
reg byte_counter = 0;
reg samples_to_send = 0;
reg samples_sent = 0;
reg clocks_per_sample = 0;
reg clock_counter = 0;
reg dio_output_sequence_state = 2'b00;
// State defines
parameter STATE_IDLE = 2'b00;
parameter STATE_OUPUTTING = 2'b01;
wire setup_dio_sequence_register_ch1;
assign setup_dio_sequence_register_ch1 = ((chipselect_n == 1'b0) & (write == 1'b1) & (address == SETUP_DIO_SEQUENCE_REG_ADDRESS_BANK1));
always @ (posedge clk or negedge reset_n)
begin
if(~reset_n)
begin
// Initialise variables
byte_counter <= 0;
samples_to_send <= 0;
samples_sent <= 0;
clocks_per_sample <= 0;
clock_counter <= 0;
dio_output_sequence_state <= STATE_IDLE;
end
else if(setup_dio_sequence_register_ch1) // Receive and store sequence message
begin
// Store message byte
act_message <= writedata;
if (byte_counter < 511)
begin
// Message not complete yet, increment byte counter
byte_counter <= byte_counter + 1;
end
else
begin
// Complete message received
byte_counter <= 0;
samples_to_send <= {act_message, act_message, act_message, act_message};
clocks_per_sample <= 50*({act_message, act_message, act_message, act_message}); // Minimum sample time = 50 clock cycles = 1uS
// Start sending output samples
clock_counter <= 0;
samples_sent <= 0;
dio_output_sequence_state <= STATE_OUPUTTING;
end
end
else // Send sequence message output
begin
case (dio_output_sequence_state)
STATE_IDLE:
begin
clock_counter <= 0;
samples_sent <= 0;
end
STATE_OUPUTTING:
begin
if (samples_to_send == 0)
begin
// Empty sequence
dio_output_sequence_state <= STATE_IDLE;
end
else if (clock_counter == 0)
begin
// Send sample
w_dio_output_bank1 <= act_message;
// Check for end of sequence
if (samples_sent < (samples_to_send-1))
begin
// Increment samples_sent and reload counter
samples_sent <= samples_sent + 1;
clock_counter <= (clocks_per_sample - 1);
end
else
begin
// End sequence
//dio_output_sequence_state <= STATE_IDLE;
// Restart sequence
samples_sent <= 0;
clock_counter <= (clocks_per_sample - 1);
end
end
else
begin
// Decrement reload counter
clock_counter <= clock_counter - 1;
end
end
endcase
end
end
endmodule